承诺链与 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()。
我有一个任务是使用量角器输入通知日期 我需要在进入之前清除内容所以我想出了这个代码
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()。