承诺链 vs promise.all [英] promise chaining vs promise.all

查看:23
本文介绍了承诺链 vs promise.all的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用量角器输入通知日期的任务在进入之前我需要清除内容所以我想出了这个代码

 this.Then(/^我应该输入通知日期"$/, () => {const d = 新日期();返回 orderCheckOutPage.pageElements.recipientNotificationDateMonth.clear().then(() => {返回 orderCheckOutPage.pageElements.recipientNotificationDateMonth.sendKeys(d.getMonth() + 1).then(() => {返回 orderCheckOutPage.pageElements.recipientNotificationDateDay.clear().then(() => {返回 orderCheckOutPage.pageElements.recipientNotificationDateDay.sendKeys(d.getDate()).then(() => {返回 orderCheckOutPage.pageElements.recipientNotificationDateYear.clear().then(() => {返回 orderCheckOutPage.pageElements.recipientNotificationDateYear.sendKeys(d.getFullYear())})})})})})});

我朋友告诉我上面的代码可以重构为

const promises = [];promises.push(orderCheckOutPage.pageElements.recipientNotificationDateMonth.clear());promises.push(orderCheckOutPage.pageElements.recipientNotificationDateMonth.sendKeys(d.getMonth() + 1));promises.push(orderCheckOutPage.pageElements.recipientNotificationDateDay.clear());promises.push(orderCheckOutPage.pageElements.recipientNotificationDateDay.sendKeys(d.getDate()));promises.push(orderCheckOutPage.pageElements.recipientNotificationDateYear.clear());promises.push(orderCheckOutPage.pageElements.recipientNotificationDateYear.sendKeys(d.getFullYear()));返回 promise.all(promises);

听说promise.all会开始一一解析promise

首先它会转到第一个语句并尝试解决它是否[在上述情况下是明确的月份]如果是异步的它会跳到第二个并尝试执行语句[将密钥发送到月份]

这里清除和进入的任务将并行运行

并根据承诺得到解决的时间执行任务

如果是这种情况,sendkeys 是否有可能在清除之前被执行

如果我错了请纠正我......!!!!!!

解决方案

Protractor 有自己的 promise 管理机制,叫做控制流,简单理解控制流,你可以认为它是一个队列.

当nodejs逐行执行你的量角器脚本时,如果该行中的表达式返回一个promise,控制流会将promise添加到队列中.

所有行执行完成后,你会得到一个promise队列,此时你的测试还没有完成,因为控制流会让你的测试等待队列中的所有promise被执行.现在控制流将从队列中弹出一个承诺并执行并等待它完成,然后下一个承诺.

所以有了这样的机制,你的脚本可以按照你写的顺序执行在文件中.实际上控制流的作用比我在这里说的要复杂.

在你的情况下你不需要使用嵌套的 then 链,你的代码就像回调金字塔,不代表 promise 的优势(promise 是解决回调金字塔).您的代码可以很简单,如下所示:

const d = new Date();//输入月份orderCheckOutPage.pageElements.recipientNotificationDateMonth.clear();orderCheckOutPage.pageElements.recipientNotificationDateMonth.sendKeys(d.getMonth() + 1);//输入日期orderCheckOutPage.pageElements.recipientNotificationDateDay.clear();orderCheckOutPage.pageElements.recipientNotificationDateDay.sendKeys(d.getDate());//输入年份orderCheckOutPage.pageElements.recipientNotificationDateYear.clear();orderCheckOutPage.pageElements.recipientNotificationDateYear.sendKeys(d.getFullYear());

对于您的情况,无需使用 promise.all(),因为您的代码的所有交互都不会从页面中获取某些值.我会举一个例子来帮助你学习在这种情况下最好使用 promise.all():

假设我有一个页面,它显示价格和金额.我需要按价格*金额计算费用.

使用嵌套 then 链:

var fee = ele_price.getText().then(function(price){返回 ele_amount.getText().then(function(amount){退货价格*金额;});});费用.然后(功能(费用){控制台日志(费用);});

使用 promise.all():

var fee = promise.all([ele_price.getText(),ele_amount.getText()]).then(函数(数据){var 价格 = 数据 [0];var 数量 = 数据 [1];退货价格*金额;});费用.然后(功能(费用){控制台日志(费用);});

所以使用promise.all(),一个then()就够了.这使您的代码比嵌套 then 链更具可读性.

希望您现在明白为什么不需要在您的情况下使用 promise.all().

i have a task to enter the notification date using protractor where i need to clear contents before entering so i have came up with this code

 this.Then(/^I should enter "Notification Date"$/, () => {
    const d = new Date();
    return orderCheckOutPage.pageElements.recipientNotificationDateMonth.clear().then(() => {
        return orderCheckOutPage.pageElements.recipientNotificationDateMonth.sendKeys(d.getMonth() + 1).then(() => {
            return orderCheckOutPage.pageElements.recipientNotificationDateDay.clear().then(() => {
                return orderCheckOutPage.pageElements.recipientNotificationDateDay.sendKeys(d.getDate()).then(() => {
                    return orderCheckOutPage.pageElements.recipientNotificationDateYear.clear().then(() => {
                        return orderCheckOutPage.pageElements.recipientNotificationDateYear.sendKeys(d.getFullYear())
                    })
                })
            })
        })
    })
});

my friend told me the above code be can refactored as

const promises = []; promises.push(orderCheckOutPage.pageElements.recipientNotificationDateMonth.clear()); promises.push(orderCheckOutPage.pageElements.recipientNotificationDateMonth.sendKeys(d.getMonth() + 1)); promises.push(orderCheckOutPage.pageElements.recipientNotificationDateDay.clear()); promises.push(orderCheckOutPage.pageElements.recipientNotificationDateDay.sendKeys(d.getDate())); promises.push(orderCheckOutPage.pageElements.recipientNotificationDateYear.clear()); promises.push(orderCheckOutPage.pageElements.recipientNotificationDateYear.sendKeys(d.getFullYear())); return promise.all(promises);

I heard promise.all will start resolving promises one by one

first it would go to first statement and try to resolve if it [here in the above case is clear month] if is asynch the it would jump to second one and try to execute the statement [sending keys to month]

here both the tasks of clearing and entering will be run parallely

and tasks are executed based on the time promises get resolved

if it is that case will there be chances of sendkeys being exeuted before clearing

correct me if i am wrong...!!!!!

解决方案

Protractor has its own promise manage mechanism called control flow, To understand control flow simply, you can think it is a queue.

When nodejs execute your Protractor script line by line, if the expression in the line return a promise, control flow will add the promise into the queue.

After all lines execute done, you will get a promise queue, at this time point your testing had not finish yet, because control flow will make your testing to wait all promise in the queue be executed. Now control flow will pop a promise from the queue and execute and wait it complete, then next promise.

So with such mechanism, your script can be executed as the order as you write down in file. Actually what control flow did is more complex than I said here.

You no need to use nested then chain in your case, your code like the callback pyramid, not represent the advantage of promise (promise is to resolve callback pyramid). Your code can be simple as below:

const d = new Date();
//input month
orderCheckOutPage.pageElements.recipientNotificationDateMonth.clear();
orderCheckOutPage.pageElements.recipientNotificationDateMonth.sendKeys(d.getMonth() + 1);
//input day
orderCheckOutPage.pageElements.recipientNotificationDateDay.clear();
orderCheckOutPage.pageElements.recipientNotificationDateDay.sendKeys(d.getDate());
//input year
orderCheckOutPage.pageElements.recipientNotificationDateYear.clear();
orderCheckOutPage.pageElements.recipientNotificationDateYear.sendKeys(d.getFullYear());

For your case, no need to use promise.all(), because all interaction of your code not to get some value from page. I will give an example to help you learn in which case it's better to use promise.all():

Assume i have a page and it display a price and a amount. I need to calculate the fee by price * amount.

Use nested then chain:

var fee = ele_price.getText().then(function(price){

    return ele_amount.getText().then(function(amount){
        return price * amount;
    });
});

fee.then(function(fee){
    console.log(fee);
});

Use promise.all():

var fee = promise.all([
  ele_price.getText(),
  ele_amount.getText()
])
.then(function(datas){
    var price = datas[0];
    var amount = datas[1];
    return price * amount;
});

fee.then(function(fee){
    console.log(fee);
});

So use promise.all(), one then() is enough. This makes your code more readable than nested then chain.

Hope you now understand why no need to use promise.all() in your case.

这篇关于承诺链 vs promise.all的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆