如何从内部的承诺返回然后阻止?

gui*_*job 1 javascript promise

我试图了解promise级联如何正常工作。为此,我创建了一个函数,它返回一个新的Promisecallback functions在其范围内有一些:

exports.function1 = (params) => {
  return new Promise((resolve, reject) => {
    // do something sync

    someFunctionAsyncWithCallback(params, (err, data) => { //async func
      err ? reject(err) : resolve(data);
    })
  }).then(data => {
     // do something sync again

    anotherAsyncFunctionWithCallback(data, function (err, response) {
      return err ? Promise.reject(err) : Promise.resolve(response);
      // return err ? reject(err) : resolve(response); ?
    });
  })
}
Run Code Online (Sandbox Code Playgroud)

then块内部,我如何正确制作return以继续级联过程?在executor有决心/拒绝,我可以为了继续链接调用函数。但是,一旦我们开始then执行,这些功能就不存在了——如果我错了,请纠正我——我不知道如何继续。

任何评论将不胜感激。

T.J*_*der 5

避免将承诺链与回调风格的 API 结合使用。相反,使用承诺包装器包装回调风格的 API,然后让您合理地组合事物。

您引用的示例看起来像 NodeJS API。如果您使用的是 Node、v8 及更高版本,utils.promisify它可用于快速轻松地将标准 NodeJS 回调样式函数包装到返回承诺的函数中。

// Get promise-enabled versions:
const promiseSomeFunctionAsyncWithCallback = utils.promisify(someFunctionAsyncWithCallback);
const promiseAnotherAsyncFunctionWithCallback = utils.promisify(anotherAsyncFunctionWithCallback);

// Use them:
exports.function1 = (params) => {
  return promiseSomeFunctionAsyncWithCallback(params)
    .then(promiseAnotherAsyncFunctionWithCallback);
  })
};
Run Code Online (Sandbox Code Playgroud)

如果您没有使用 Node,或者您使用的是旧版本,那么 没有什么神奇之处utils.promisify,您可以轻松推出自己的:

const promisify = f => return function(..args) {
    return new Promise((resolve, reject) => {
        f.call(this, ...args, (err, result) => {
            if (err) {
                reject(err);
            } else {
                resolve(result);
            }
        });
    });
};
Run Code Online (Sandbox Code Playgroud)

回复您的评论:

我在这些回调函数之间有一些同步代码。在你的第一个例子中你会如何处理它?

有两种风格:

1.then仅当您到达下一个异步位时才将同步代码放入回调和链中:

exports.function1 = (params) => {
  // Code here will run synchronously when `function1` is called
  return promiseSomeFunctionAsyncWithCallback(params)
    .then(result => {
        // You culd have synchronous code here, which runs when
        // this `then` handler is called and before we wait for the following:
        return promiseAnotherAsyncFunctionWithCallback(result);
    });
  })
};
Run Code Online (Sandbox Code Playgroud)

2. 将同步代码放在自己的then回调中:

exports.function1 = (params) => {
  // Code here will run synchronously when `function1` is called
  return promiseSomeFunctionAsyncWithCallback(params)
    .then(result => {
        // You culd have synchronous code here, which runs when
        // this `then` handler is called.
        // Pass on the result:
        return result;
    })
    .then(promiseAnotherAsyncFunctionWithCallback);
  })
};
Run Code Online (Sandbox Code Playgroud)

#2 的一个优点是每个不同的逻辑步骤都是它自己的块。这确实意味着在主事件循环的这次迭代结束时向微任务循环返回一个额外的收益,但这不太可能成为问题。