Javascript 如何从一个承诺中返回然后阻止?

Javascript 如何从一个承诺中返回然后阻止?,javascript,promise,Javascript,Promise,我试图理解promise的级联是如何正常工作的。为此,我创建了一个函数,该函数返回一个新的承诺,但在其作用域中有一些回调函数: exports.function1 = (params) => { return new Promise((resolve, reject) => { // do something sync someFunctionAsyncWithCallback(params, (err, data) => { //async func

我试图理解promise的级联是如何正常工作的。为此,我创建了一个函数,该函数返回一个新的承诺,但在其作用域中有一些回调函数:

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块中,如何正确返回以继续级联过程?在executor中,我可以调用resolve/reject函数来继续链接。但是,一旦我们进入then执行,这些函数就不存在了——如果我错了,请纠正我——我不知道如何继续


如有任何意见,我们将不胜感激。

您需要回复另一个承诺:

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

你需要回报另一个承诺:

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

避免将承诺链与回调风格的API相结合。相反,使用promise包装器包装回调风格的API,这样可以让您合理地编写内容

您引用的示例看起来像NodeJS API。如果您使用的是Node、v8和更高版本,则可以使用它快速方便地将标准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);
  })
};
如果您没有使用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);
            }
        });
    });
};
请回复您的评论:

我在这些回调函数之间有一些同步代码。。在第一个示例中,您将如何处理它

这有两种风格:

一,。只有在到达下一个异步位时,才将同步代码放入然后的回调和链中:

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);
    });
  })
};
二,。将同步代码放入其自己的回调中,然后执行以下操作:

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的一个优点是每个不同的逻辑步骤都是它自己的块。这确实意味着在主事件循环的迭代结束时会有一个额外的让步返回到微任务循环,但这不太可能是一个问题。

避免将承诺链与回调风格的API相结合。相反,使用promise包装器包装回调风格的API,这样可以让您合理地编写内容

您引用的示例看起来像NodeJS API。如果您使用的是Node、v8和更高版本,则可以使用它快速方便地将标准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);
  })
};
如果您没有使用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);
            }
        });
    });
};
请回复您的评论:

我在这些回调函数之间有一些同步代码。。在第一个示例中,您将如何处理它

这有两种风格:

一,。只有在到达下一个异步位时,才将同步代码放入然后的回调和链中:

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);
    });
  })
};
二,。将同步代码放入其自己的回调中,然后执行以下操作:

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的一个优点是每个不同的逻辑步骤都是它自己的块。这确实意味着在主事件循环的迭代结束时会有一个额外的让步返回到微任务循环,但这不太可能是一个问题。

只需从内部调用另一个函数,然后该函数与resolve、reject级联??只需从内部调用另一个函数,然后与resolve、reject级联??谢谢您的回答。我实际上是在使用Node7.10,并使用bluebird进行宣传。听着,我在这些回调函数之间有一些同步代码。。在第一个示例中,您将如何处理它?我不知道then子句可以返回值而不是承诺。现在阅读这篇文章,我们清楚地表明,如果handler函数:返回一个值,那么返回的承诺将以返回的值作为其值进行解析。。谢谢你的指点out@guijob:-then处理程序不仅可以返回非承诺值,而且它还可以返回非常常见的值。:-然后,它本身,总是返回到一个适当的位置;then处理程序返回的内容只决定了该承诺的解决方式。@guijob:No,如果它在初始部分抛出,则没有什么可以将其转换为拒绝。如果要执行此操作,最简单的方法可能是返回Promise.resolve.then=>{/*…sync code…*/}。then=>PromiseSomeFunctionSyncWithCallbackParams.thenpromiseAnotherAsyncFunctionWithCallback;。那里的同步代码直到当前事件循环结束时的微任务循环才会运行,它引发的任何异常都将成为拒绝。@guijob:您可能还看到,当前Chrome、Firefox和Edge中支持的ES2017+功能,这使很多事情都变得简单,但并非所有事情都是如此。他们是信守诺言的人。但是,你知道,这是一种很好的糖。谢谢你的回答。我实际上是在使用Node7.10,并使用bluebird进行宣传。听着,我在这些回调函数之间有一些同步代码。。在第一个示例中,您将如何处理它?我不知道then子句可以返回值而不是承诺。现在阅读这篇文章,我们清楚地表明,如果handler函数:返回一个值,那么返回的承诺将以返回的值作为其值进行解析。。谢谢你
你说得对out@guijob:-then处理程序不仅可以返回非承诺值,而且它还可以返回非常常见的值。:-然后,它本身,总是返回到一个适当的位置;then处理程序返回的内容只决定了该承诺的解决方式。@guijob:No,如果它在初始部分抛出,则没有什么可以将其转换为拒绝。如果要执行此操作,最简单的方法可能是返回Promise.resolve.then=>{/*…sync code…*/}。then=>PromiseSomeFunctionSyncWithCallbackParams.thenpromiseAnotherAsyncFunctionWithCallback;。那里的同步代码直到当前事件循环结束时的微任务循环才会运行,它引发的任何异常都将成为拒绝。@guijob:您可能还看到,当前Chrome、Firefox和Edge中支持的ES2017+功能,这使很多事情都变得简单,但并非所有事情都是如此。他们是信守诺言的人。但是,你知道,好的糖。