javascript - 并行 promise 的流动构建

标签 javascript node.js promise bluebird

我的问题是关于 BlueBird 中 promise 的优雅并行化当您需要将上下文和参数传递给构建 promise 的函数时。

为了使我的问题易于理解和测试,我制作了一个没有依赖性的示例。

假设我进行涉及异步“计算机”(必须释放其资源)的计算( 1/(xxx) + 1/(x*x) )。正方形和立方体是异步且独立计算的。

我可以这样进行计算:

InitComputer(2) // returns a promise
.then(invert)
.then(function(arg){
    return Promise.all([
        proto.square(arg),
        proto.cube(arg)
    ]);
}).spread(function(sq, cu){
    this.set(sq + cu);
}).catch(function(err){
    console.log('err:', err);
}).finally(endComputer);

但我发现与理论上可能的情况相比,all 的这种用法过于繁重。当您将函数作为参数传递给 then 时,它就会被执行。当您将函数传递给 all 时,它们没有传递,而是出现错误。我怀疑我缺少一个实用程序或模式...

有没有解决方案可以将其更改为这种风格的更简单的东西:

InitComputer(2)
.then(invert)
.all([
    proto.square,
    proto.cube
]).spread(function(sq, cu){
    this.set(sq + cu);
}).catch(function(err){
    console.log('err:', err);
}).finally(endComputer);

我可能可以破解 Promise.prototype.all或者定义一个新函数以避免增加多态性,但我只对不涉及修改我不拥有的对象的解决方案感兴趣。


附件:

以下是如何定义我的测试的“计算机”:

var Promise = require("bluebird");

function Computer(){}
function InitComputer(v){
    // initializing a computer is asynchronous and may fail hence the promise
    var c = new Computer(), resolver = Promise.defer();
    setTimeout(function(){
        if (v>1) resolver.resolve(v);
        else resolver.reject(new Error("bad value: "+v));
    },100);
    return resolver.promise.bind(c);
}
var proto = Computer.prototype;
proto.square = function(x){
    // imagine this really uses the computer and is asynchronous
    if (!this instanceof Computer) throw new Error('not a computer');
    return x*x
}
proto.cube = function(x){ return x*x*x }
proto.set = function(v){ this.value = v }

function endComputer(){
    // releases resources here
    console.log('value:', this.value);
}

// this asynchronous function doesn't involve or know the computer
function invert(v){ return 1/v }

最佳答案

您不必在那里使用Promise.all。而不是这样做:

.then(function(arg){
    return Promise.all([
        proto.square(arg),
        proto.cube(arg)
    ]);
}).spread(...

您可以简单地使用:

.then(function(arg){
    return [proto.square(arg), proto.cube(arg)];
}).spread(...

如果我们在 Node.js 中有箭头函数,它就会像这样简单:

.then(arg => [proto.square(arg), proto.cube(arg)]).spread(...
当您需要启动具有至少 2 个 Promise 的 Promise 链时,可以使用

Promise.all 。例如:

var promise1 = somePromise();
var promise2 = somePromise2();

// Start the chain here
Promise.all([promise1, promise2])
.spread(function(value1, value2) {
    // ...
});

关于javascript - 并行 promise 的流动构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21015511/

相关文章:

javascript - 用 bluebird promise 迭代数组

javascript - 为什么最后两个函数起作用,而第一个不起作用?

javascript - Angular JS 中的递归 promise

javascript - Discord 语音消息插件 : getUserMedia() is not supported

javascript - 为什么 React Router Dom 的链接返回时不刷新?

javascript - 从 Promise 返回非返回函数导致警告

node.js在发出http请求时区分错误

javascript - 加载资源而不显示 "loading"微调器

javascript - 我可以在 HTML 的 iframe 中添加复选框吗

node.js - 在 node.js 中使用 pg-postgres 的正确方法?