我有一项任务是使用量角器输入通知日期 我需要在进入之前清除内容,所以我想出了这个代码
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 如果我错了,请纠正我...... !!!!!答案 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()。