promise chaining vs promise.all

限于喜欢 提交于 2019-12-31 05:34:10

问题


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...!!!!!


回答1:


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.



来源:https://stackoverflow.com/questions/47401898/promise-chaining-vs-promise-all

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!