【问题标题】:Promise resolve not waiting for promise inside it承诺解决不等待其中的承诺
【发布时间】:2018-03-19 11:33:00
【问题描述】:

我正在尝试打一个休息电话并更新一个列表,然后用更新的列表解决这个承诺。

function addTestCaseToTestRail(){
    return new Promise(function(resolve){
        compareTestRailAndProtractor().then(function(tests){
            var testsLength = tests.tests.length;
            var url = testRailURL+testRailData.addTestEndPoint;

            for(var i=0; i<testsLength; i++){
                if(tests.tests[i].id==undefined){
                    var newId=""
                    var options = {
                        url:url,
                        headers:headers,
                        body:{
                            "title":tests.tests[i].name,
                            "custom_jira_component" : 465
                        },
                        json: true
                    }
                    request.post(options, function(err, httpResponse, body){
                        if (err) {
                            console.error(err);
                            return;
                        }
                        newId = body.id;
                    });
                    tests.tests[i].id = newId;
                }
            }
            resolve(tests);
        });
    });
}

function test(){
    addTestCaseToTestRail().then(function(tests){
        console.log(tests);
    });
}

test()

请求正在发布,我可以在测试轨道中创建测试,但 resolve(tests) 没有 newId 分配。 这是我得到的输出。不知道为什么 resolve 不等待其余调用完成。

{ tests: 
    [ { id: '', name: 'test1'},
      { id: '', name: 'test2'},
      { id: '', name: 'test3'},
      { id: '', name: 'test4'},
      { id: '', name: 'test6'},
      { id: '', name: 'test5'} ] }

【问题讨论】:

  • 如果if(tests.tests[i].id==undefined) 评估为假会发生什么?
  • 没什么,只是继续循环迭代。我们可以假设所有的 id 都是未定义的
  • 在您对request() 的任何调用实际完成之前,您正在解决承诺。它们是异步的。在您的for 循环完成后,它们会稍后完成。这里还有许多其他问题/答案展示了如何处理此类问题。

标签: javascript node.js promise request


【解决方案1】:

我认为这是因为 Javascript 的非阻塞特性。问题是“解决(测试)”在您的“发布”事件有响应之前执行(这是您从中获取 Id 的地方)。

我建议您看看https://caolan.github.io/async/ Async 是一个用于处理异步进程的出色库。

祝你好运!

编辑:你也可以看看async/awaitJS操作符

【讨论】:

  • 这并不是真正的解决方案。再加上当 OP 已经在使用 Promise 并且我们有 async/await 时推荐 async 库并没有什么意义。
【解决方案2】:

compareTestRailAndProtractor 返回一个Promise。您可以在 .then()for 循环内的 Promise 构造函数中使用 async/await 来等待 request 回调,这是问题代码中的问题,因为 for 循环不等待回调函数

function addTestCaseToTestRail() {
  return compareTestRailAndProtractor()
    .then(async function(tests) {
        var testsLength = tests.tests.length;
        var url = testRailURL + testRailData.addTestEndPoint;

        for (var i = 0; i < testsLength; i++) {
          await new Promise((resolve, reject) => {
              if (tests.tests[i].id == undefined) {
                var newId = ""
                var options = {
                  url: url,
                  headers: headers,
                  body: {
                    "title": tests.tests[i].name,
                    "custom_jira_component": 465
                  },
                  json: true
                }
                request.post(options, function(err, httpResponse, body) {
                  if (err) {
                    reject(err);
                  }
                  newId = body.id;
                  tests.tests[i].id = newId;
                  resolve();
                });

              } else {
                resolve()
              }    
          });
      }
      return tests
    })
}

function test() {
  addTestCaseToTestRail()
    .then(function(tests) {
      console.log(tests);
    })
    .catch(function(err) {
      console.error(err)
    })
}

test()

【讨论】:

    猜你喜欢
    • 2019-04-29
    • 1970-01-01
    • 2017-04-04
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    相关资源
    最近更新 更多