Javascript 平行承诺的流体构造

Javascript 平行承诺的流体构造,javascript,node.js,promise,bluebird,Javascript,Node.js,Promise,Bluebird,我的问题是关于在需要将上下文和参数传递给构建承诺的函数时,承诺的优雅并行化 为了让我的问题可以理解和测试,我做了一个没有依赖性的例子 让我们假设我进行计算1/xxx+1/x*x,涉及一台异步计算机,它的资源必须被释放。正方形和立方体是异步独立计算的 我可以这样计算: InitComputer(2) // returns a promise .then(invert) .then(function(arg){ return Promise.all([ proto.squar

我的问题是关于在需要将上下文和参数传递给构建承诺的函数时,承诺的优雅并行化

为了让我的问题可以理解和测试,我做了一个没有依赖性的例子

让我们假设我进行计算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);
但我发现,与理论上可能的情况相比,这种用法太重了。当您将函数作为参数传递给then时,它将被执行。当您将函数传递给所有人时,它们不是,这是一个错误。我怀疑我错过了一个实用程序或模式

是否有一种解决方案可以将其更改为更简单的样式:

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

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

附件:

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

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 }
你不必用承诺,一切都在那里。而不是做:

.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个承诺的承诺时,就要使用all。例如:

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

// Start the chain here
Promise.all([promise1, promise2])
.spread(function(value1, value2) {
    // ...
});
你不必用承诺,一切都在那里。而不是做:

.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个承诺的承诺时,就要使用all。例如:

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

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

对于您提到的资源管理用例,bluebird提供了。使用Promise.using可以设置函数,以便在完成使用时自动关闭异步检索的资源

也有助于将多维数据集和方形异步方法的结果结合起来

在这里,我稍微重写了InitComputer示例来说明它是如何工作的——它现在返回添加了val作为属性的计算机实例,而不是val,并且我还将endComputer放在proto上

注意:您可以像这样使用Promise.method,而不是返回延迟的:

var invert=Promise.methodfunction invertv{return 1/v}

新电脑:

新代码:


对于您提到的资源管理用例,bluebird提供了。使用Promise.using可以设置函数,以便在完成使用时自动关闭异步检索的资源

也有助于将多维数据集和方形异步方法的结果结合起来

在这里,我稍微重写了InitComputer示例来说明它是如何工作的——它现在返回添加了val作为属性的计算机实例,而不是val,并且我还将endComputer放在proto上

注意:您可以像这样使用Promise.method,而不是返回延迟的:

var invert=Promise.methodfunction invertv{return 1/v}

新电脑:

新代码:


它并不像我希望的那么简单,但它确实可以接受。我想知道为什么所有的,与之相反的,都不在参数中执行函数。@dystroy hah,主要是关于使用this.square和this.cube。它并不像我希望的那么简单,但它确实可以接受。我想知道为什么所有的,与之相反,不执行参数中的函数。@哈,主要是关于使用this.square和this.cube。我可能出了点问题,但proto.squarearg和proto.cubearg不是在将结果传递给数组构造函数以获得承诺之前立即计算的吗?全部?编辑哦,好吧,它们可能应该是异步的,没关系。@Groo完全正确。想象一下,这真的使用了计算机并且是异步的。为了让问题可读,我编写了最简单的代码,因此我不得不采取一些捷径。我可能有点错误,但proto.squarearg和proto.cubearg不是在将结果传递给数组构造函数以获得Promise.all之前立即求值的吗?编辑哦,好吧,它们可能应该是异步的,没关系。@Groo完全正确。想象一下,这真的使用了计算机并且是异步的。我制作了最简单的代码以使问题可读,因此我必须采取一些快捷方式..+1但您正在使用Promise.using等功能回答一个已回答的老问题,而这些功能在提问时不可用。重提这个老问题有点麻烦。请注意,《蓝鸟》的作者现在宣布Promise.defer为反模式,因为他更喜欢更简单的新Promisef1,f2。谢谢你,是的,来晚了,但这在我的搜索中排在第一位,所以我想我会花费0.02美元。。我还发现,答案在本主题中也非常有用+1,但您回答的是一个已经回答过的老问题,其功能如Promise.using,在提问时不可用。重提这个老问题有点麻烦。注意Promise.defe
《蓝鸟》的作者现在宣布r是一个反模式,因为他更喜欢更简单的新Promisef1,f2。谢谢你,是的,来晚了,但这在我的搜索中排在第一位,所以我想我会广告0.02美元。。我也发现这个答案在这个话题上也很有帮助