承诺链与 promise.all

promise chaining vs promise.all

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

 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会开始一一解决promise

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

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

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

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

如有错误请指正...!!!!!

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

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

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

所以有了这样的机制,你的脚本就可以按照你写的顺序执行 在文件中。其实控制流做的比我这里说的要复杂

你的情况不需要使用nested then chain,你的代码像回调金字塔,不代表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(),一个then()就够了。这使您的代码比 nested then chain 更具可读性。

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