承诺链接vs promise.all

时间:2017-11-20 22:05:57

标签: selenium protractor cucumber angular-promise

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

 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())
                    })
                })
            })
        })
    })
});

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

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);

我听说promise.all将逐一解决承诺

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

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

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

如果是这种情况,那么在清除

之前就有机会执行sendkeys 如果我错了,请纠正我...... !!!!!

1 个答案:

答案 0 :(得分:1)

Protractor有自己的承诺管理机制,称为控制流,为了简单地理解控制流,你可以认为它是一个队列。

当nodejs逐行执行Protractor脚本时,如果行中的表达式返回一个promise,则控制流会将promise添加到队列中。

在所有行执行完毕后,您将获得一个承诺队列,此时您的测试尚未完成,因为控制流将使您的测试等待队列中的所有承诺执行。现在,控制流将从队列中弹出一个promise并执行并等待它完成,然后是下一个promise。

因此,使用这种机制,您的脚本可以在编写时按顺序执行 在文件中。实际上控制流程的作用比我在这里说的要复杂得多。

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

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());

对于您的情况,不需要使用promise.all(),因为您的代码的所有交互都不能从页面获取某些值。我将举一个例子来帮助您了解在哪种情况下使用promise.all()更好:

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

使用嵌套然后链:

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);
});

使用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);
});

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

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