管理承诺依赖项

Tom*_*ell 9 javascript node.js promise bluebird

我正在使用Node.js和Bluebird创建一些相当复杂的逻辑,包括解压缩结构化文件,解析JSON,创建和更改几个MongoDB文档,以及在多个位置编写相关文件.我还对所有这些进行了相当复杂的错误处理,具体取决于发生错误时系统的状态.

我很难想出通过承诺流来管理依赖关系的好方法.

我现有的代码基本上是这样的:

var doStuff = function () {
  var dependency1 = null;
  var dependency2 = null;

  promise1()
  .then(function (value) {
    dependency1 = value;

    return promise2()
    .then(function (value) {
      dependency2 = value;

      return promise3(dependency1)
      .then(successFunction);
    });
  })
  .catch(function (err) {
    cleanupDependingOnSystemState(err, dependency1, dependency2);
  });
};
Run Code Online (Sandbox Code Playgroud)

请注意,在promise3之前不需要dependency1,并且错误处理程序需要知道依赖项.

对我而言,这似乎是意大利面条代码(而且我的实际代码在很多并行控制流程中更糟糕).我还读过,在.then回调中返回另一个承诺是反模式.是否有更好/更清洁的方式来完成我想要做的事情?

Ben*_*aum 10

我发现这两个答案目前提供的很好但很笨拙.他们都很好,但包含开销,我认为你不需要.如果您使用promises作为代理,您可以免费获得很多东西.

var doStuff = function () {
  var p1 = promise1();
  var p2 = p1.then(promise2);
  var p3 = p1.then(promise3); // if you actually need to wait for p2 here, do.
  return Promise.all([p1, p2, p3]).catch(function(err){
      // clean up based on err and state, can unwrap promises here
  });
};
Run Code Online (Sandbox Code Playgroud)

请不要使用successFunction,这样的反模式和丢失信息.如果您觉得必须使用successFunction,可以写:

var doStuff = function () {
  var p1 = promise1();
  var p2 = p1.then(promise2);
  var p3 = p1.then(promise3); // if you actually need to wait for p2 here, do.
  Promise.join(p1, p2, p3, successFunction).catch(function(err){
      // clean up based on err and state, can unwrap promises here
  });
};
Run Code Online (Sandbox Code Playgroud)

然而,它无限恶化,因为它不会让消费者处理他们可能能够处理的错误.