如何从内部的承诺返回然后阻止? [英] How to return from a promise inside then block?

查看:43
本文介绍了如何从内部的承诺返回然后阻止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解 promise 的级联如何正常工作.为此,我创建了一个函数,它返回一个新的 Promise 但在其作用域中有一些 回调函数:

I'm trying to understand how promise's cascading properly works. For this, I created a function which returns a new Promise but has some callback functions in their scope:

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 执行阶段,这些功能就不存在了 - 如果我错了,请纠正我 - 我不知道如何继续.

Inside then block, how can I made a properly return in order to continue cascading process? In executor there are resolve/reject functions which I can call in order to continue chaining. But, once we are in then execution, these function aren't there - correct me if I'm wrong - and I don't know how to move on.

任何评论将不胜感激.

推荐答案

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

Avoid combining promise chains with callback-style APIs. Instead, wrap the callback-style API with a promise wrapper, which then lets you compose things reasonably.

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

The examples you've quoted look like NodeJS APIs. If you're using Node, v8 and higher have utils.promisify which can be used to quickly and easily wrap standard NodeJS-callback-style functions to functions returning promises.

// 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 没有什么神奇之处,您可以轻松地推出自己的:

If you're not using Node, or you're using an old version, there's nothing magic about utils.promisify, you can easily roll your own:

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

<小时>

重新评论:


Re your comment:

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

I have some sync code between these callback functions.. How would you handle it in your first example?

有两种风格:

1.将同步代码放在 then 回调中,并仅在您到达下一个异步位时链接:

1. Put the sync code in the then callback and chain only when you reach your next async bit:

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 回调中:

2. Put the sync code in its own then callback:

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

One advantage to #2 is that each distinct logical step is its own block. It does mean one additional yield back to the microtask loop at the end of this iteration of the main event loop, but that's not likely to be an issue.

这篇关于如何从内部的承诺返回然后阻止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆