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

时间:2018-02-19 13:33:15

标签: javascript promise

我试图理解promise的级联是如何正常运作的。为此,我创建了一个函数,该函数返回一个新的Promise,但在其范围内有一些callback 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); ?
    });
  })
}

then内部,如何才能正常return才能继续进行级联处理?在executor中有解析/拒绝功能,我可以调用它们来继续链接。但是,一旦我们执行then,这些功能就不存在 - 如果我错了,请纠正我 - 而且我不知道如何继续前进。

任何评论都将不胜感激。

2 个答案:

答案 0 :(得分:3)

你需要返回另一个Promise:

return new Promise((res, rej) => anotherAsyncFunctionWithCallback(data, (err, data) => err ? rej(err) : res(data));

然而,宣传这个功能是有道理的:

 const promisify = f => (...args) => new Promise((res, rej) => f(...args, (err, data) => err? rej(err) : res(data)));

const asyncF = promisify(AsyncFunctionWithCallback);

所以可以这样做:

asyncF(1).then(asyncF).then(console.log);

答案 1 :(得分:3)

避免将promise链与回调式API结合使用。相反,使用promise包装器包装回调式API,然后让你合理地组合。

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

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

// Use them:
exports.function1 = (params) => {
  return promiseSomeFunctionAsyncWithCallback(params)
    .then(promiseAnotherAsyncFunctionWithCallback);
  })
};

如果您没有使用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);
            }
        });
    });
};

重新评论:

  

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

有两种风格:

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);
    });
  })
};

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);
  })
};

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