【问题标题】:How to return promise.map (bluebird) inside a promise chain?如何在承诺链中返回 promise.map (bluebird)?
【发布时间】:2017-04-09 05:08:32
【问题描述】:

我正在使用链来控制流程,无法在step2() 中获取 promise.map 以等待它生成的所有承诺都得到解决。

这是我试图实现的流程的视觉效果。

step1() step2() step2() step2() step2() step3()

step2() 我使用的是 Bluebird 的 promise.map。

这是链条:

step1()
  .then(function() { return step2() }) 
  .then(function() { return step3() })
  .catch(function() { // handle errors })

这是我每个步骤的功能:

let step1 = function() {
  return new Promise(function(resolve, reject) {      
    // do stuff
    resolve()
  })
}

let step2 = function() {
  return new Promise(function(resolve, reject) {
    things = []      
    return Promise.map(things, function(thing) {
      // load file async with callback
    })
    resolve()
  })
}

let step3 = function() {
  return new Promise(function(resolve, reject) {      
    // do stuff
    resolve()
  })
}

我已经用timeout 测试了更多步骤的链,除了step2() 中的promise.map 之外,它按预期工作。我究竟做错了什么? :)

【问题讨论】:

  • step2 中对resolve() 的调用无法访问。 return 有效地停止执行您的代码,因此它之后的任何代码都不会被执行。

标签: javascript node.js asynchronous promise bluebird


【解决方案1】:

您没有正确调用您的resolve 回调。

let step2 = function() {
    things = []      
    return Promise.map(things, function(thing) {         
      return new Promise( function( resolve, reject ) {
          // load file async with callback
          resolve(...)
      } )
    })
}

在你的情况下,resolve() 总是被调用,因为你正在执行异步函数来加载文件。

【讨论】:

    【解决方案2】:

    问题出在第 2 步。Promise.map 已经返回承诺,所以你可以将它返回给被调用者。然后你用new Promise 的回调来扭曲异步函数。

    let step2 = function() {
      things = []      
      return Promise.map(things, function(thing) {
        // load file async with callback
        return new Promise(function(resolve, reject) {
          fileAsyncFunc(thing, function callback(err, data) {
            if(err) {
              reject(err);
              return;
            }
            resolve(data);
          });
        });
      });
    }
    

    【讨论】:

    • 它有效!但是出于好奇,如果您使用超时来伪造异步调用,它就不起作用......为什么会这样?
    • 我不太明白你的问题,你如何伪造一个超时的异步调用?这可能只是因为异步调用在超时之前完成,因此您从异步调用中获得了结果,但这不是一个好主意,因为您永远不知道哪个先完成。
    • 是的,没关系,我认为仅使用超时就可以近似执行实际的异步调用。我懒惰的测试方式。无论如何,通过实际的异步调用来加载文件,它工作得非常好,感谢您的帮助。
    猜你喜欢
    • 2014-07-05
    • 1970-01-01
    • 2017-08-06
    • 2016-09-03
    • 1970-01-01
    • 2017-11-14
    • 1970-01-01
    • 2017-04-02
    • 2023-01-27
    相关资源
    最近更新 更多