【问题标题】:Bluebird promise generators with callbacks带有回调的 Bluebird 承诺生成器
【发布时间】:2018-02-06 11:28:01
【问题描述】:

如何让 bluebird 自动将 .nodeify/.asCallback 添加到生成的 Promise 中?

在 bluebird 中,任何 Promise 实例都可以附加到节点回调机制:

Promise.resolve('foo').asCallback(callback);

但是,有时可能需要定义的不是 Promise 本身,而是一种在调用时每次都返回一个新 Promise 的方法,如下所示:

// create a new random number promise each time
Promise.method((foo, callback) => Math.random());

// create a new random number promise each time using a generator
Promise.coroutine(function *(foo, callback) {
    return Math.random();
});

在这种情况下,如果我想在 Promise 上附加一个回调处理程序,我必须在最后“人为地”这样做,使用这样的临时方法:

// create a new random number promise each time using a generator
Promise.coroutine(function *(foo, callback) {
    // do some other stuff
    return Promise.resolve(Math.random()).asCallback(callback);
});

但是,实际上,我的 promise 更加复杂,并且在这两者之间可能会发生很多事情,例如抛出未捕获的错误。如果当时没有回调处理程序附加到 Promise,则只有在使用 .catch 处理 Promise 时才能捕获错误,并且永远不会调用 callback

那么,如何让 Promise 生成器为每个生成的 Promise 附加一个回调处理程序?

【问题讨论】:

    标签: javascript node.js callback promise bluebird


    【解决方案1】:

    你不要在生成器函数中附加回调,你把它附加到调用协程的地方:

    const myPromiseFunction = Promise.coroutine(function* (foo) {
        // do some other stuff
        return Math.random();
    });
    const myCallbackFunction = (foo, callback) => {
        myPromiseFunction(foo).asCallback(callback);
    };
    // or compatible with both promise and callback usage:
    const myFunction = (foo, callback) => {
        return myPromiseFunction(foo).asCallback(callback);
    };
    

    这意味着创建两个单独的函数,但无论如何您不应该经常这样做。如果你坚持内联,你也可以使用Promise.try 代替Promise.methodPromise.spawn(已弃用!)代替Promise.coroutine,它们会立即调用该函数。

    【讨论】:

    • 嗨@bergi,感谢您的回复!不幸的是,在我的场景中,我正在尝试为第三方使用的 SDK 编写一个函数。一些第三方可能将它与 Promise 一起使用,而另一些则与回调一起使用。使用该解决方案,这些第三方必须知道自己添加.nodeify.asCallback。在可能的情况下,如果该方法能够自动兼容两者,那就更好了。
    • @arik 就我个人而言,我只会强迫他们使用承诺,这让每个人都更容易:-) 但是asCallback 返回承诺,所以你可以只使用return 并拥有一个函数两者都兼容。
    • 传道!我已经用你的第二个建议解决了这个问题:``` function(foo, callback) { return Promise.coroutine(function *(){ // do stuff here })() .asCallback(callback); } ```
    • @arik 缺少对协程的调用 - return Promise.coroutine(…)().asCallback(…);return Promise.spawn(…).asCallback(…); - 但两者都没有单独声明那么有效。
    • 你是对的,但不用担心,我只是忘记了评论中的调用。它在实际代码中就像一个魅力:)
    猜你喜欢
    • 2014-08-03
    • 2013-03-07
    • 2015-01-24
    • 2016-07-27
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2016-09-12
    相关资源
    最近更新 更多