【发布时间】:2015-02-17 16:40:11
【问题描述】:
我的问题是关于 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的数组构造函数之前,没有立即评估proto.square(arg)和proto.cube(arg)? (编辑)哦,好吧,他们可能应该是异步的,没关系。 -
@Groo 没错。 “想象一下这真的使用计算机并且是异步的”。我做了最少的代码让问题可读,所以我不得不采取一些捷径..
标签: javascript node.js promise bluebird