【问题标题】:How do I make sure that a promise is resolved before proceeding to the next lines?在继续下一行之前,如何确保已解决承诺?
【发布时间】:2014-06-30 03:35:04
【问题描述】:

假设我有以下内容:

var myFuncResult = null;                
browser.executeScript( "return myFunc();").then( function(i){
    myFuncResult = i;
    // console.log([ "myFunc is: ", i]); this is fine
});
console.log([ "myFunc is: ", myFuncResult]);
//do something about myFunctResult
myFuncResult.doSomethingElse();

现在外部的 console.log 正在记录 null,因为它在 promise 得到解决之前已经执行。我该如何防止呢?如何确保我提供的函数在 console.log 之前先执行?在继续执行其余行之前,我需要初始化 myFuncResult。

【问题讨论】:

    标签: javascript selenium-webdriver jasmine protractor


    【解决方案1】:

    没有办法做你想做的事,这是设计使然。承诺将异步运行,因此console.log 语句将始终在您的承诺得到解决之前运行。在 promise 解决后让 console.log 语句运行的正确方法是添加另一个 then 子句,如下所示:

    var myFuncResult = null;                
    browser.executeScript( "return myFunc();").then( function(i){
        myFuncResult = i;
        // console.log([ "myFunc is: ", i]); this is fine
    }).then(function() {
        console.log([ "myFunc is: ", myFuncResult]);
    });
    

    您确实需要小心处理错误情况,因为如果 promise 被拒绝,则不会调用 then 子句的第一个参数。

    是的,这可能导致意大利面承诺,但它(稍微)比回调地狱好。享受 javascripting!

    【讨论】:

    • 控制台日志对我来说并不重要,重要的是确保 var myFuncResult 可用于剩余的代码行。
    • 那么,你剩下的代码行必须和console.log语句放在同一个then块中。
    • 我需要它在 it() 函数中用于我的 jasmine 测试用例。这是一个好习惯吗?
    • 您正在测试异步代码,因此您必须在测试中处理这些承诺。
    • 如果你使用 angularjs,你可以(在你的测试中)同步解决你的 Promise。但这是 angular 的一个特殊功能,对于 angular 之外的 jasmine 没有任何可推广的特性。有关详细信息,请参阅stackoverflow.com/questions/20311118/…
    【解决方案2】:

    您可以通过在异步函数中执行此操作来避免使用回调,例如:

    async function main() {
        const myFuncResult = await browser.executeScript("return myFunc();");
        console.log([ "myFunc is: ", myFuncResult ]);
        myFuncResult.doSomethingElse();
    }
    
    main();
    

    目前所有主流浏览器都支持此功能(不支持 IE,但不再支持 IE)。 caniuse

    【讨论】:

      猜你喜欢
      • 2021-08-11
      • 1970-01-01
      • 2018-12-14
      • 2021-08-03
      • 2015-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多