javascript和承诺:如何重构/展平以下嵌套承诺?

时间:2017-07-24 20:42:49

标签: javascript ecmascript-6 promise bluebird es6-promise

我是新来的承诺,我正在阅读一段很难让我理解的代码:

  return promise
    .then(function helper0(instances) {
      return helper1(instances, options)
        .then(function helper2() {
            return bluebird.delay(3000)
              .then(function helper3() {
                return helper4(localParams, options);
              });
          }
        });
    });

如何将其重新计算到promise.then().then()...?感谢

2 个答案:

答案 0 :(得分:3)

嵌套承诺是known anti-pattern,您应该将它们链接起来:

// the structure is vertical instead of a nested pyramid
return promise
  .then(function helper0(instances) {
    return helper1(instances, options)
  })
  .then(function helper2() {
    return bluebird.delay(3000);
  })
  .then(function helper3() {
    return helper4(localParams, options);
  });

从传递给then的回调中返回一个承诺,将该承诺添加到链中。

使用arrow functions可以进一步清理它:

return promise
  .then(instances => helper1(instances, options))
  .then(() =>  bluebird.delay(3000))
  .then(() =>  helper4(localParams, options);

但请注意,使用命名函数是一种更好的调试方法,因为堆栈跟踪更易读。

答案 1 :(得分:0)

假设您的功能也使用Bluebird承诺,您可以链接您的承诺,而不是像这样嵌套它们:

return promise.then(function helper0(instances) {
    return helper1(instances, options).delay(3000);
}).then(function helper3() {
    return helper4(localParams, options);
});

如果helperX()函数不一定返回Bluebird的承诺,那么你可以这样做:

return promise.then(function helper0(instances) {
    return helper1(instances, options);
}).then(function() {
    return Bluebird.delay(3000);
}).then(function helper3() {
    return helper4(localParams, options);
});

当您从.then()处理程序中返回一个promise时,会将该promise转入链中,并且链的其余部分会在链继续之前等待该promise。这允许你像这样链而不是嵌套一切。