按顺序 运行 Q 承诺
Sequentially running Q Promises
在一个Node.js
应用程序中,我想实现这个:
读取数组,取决于项目类型,决定使用 returns 一个 Q
Promise
对象的特定函数。我希望这个过程按顺序运行。
我有这两个承诺:
var q = require('q');
Classes.prototype.fn1 = function (item) {
return q.Promise(function(resolve, reject){
Items.find({item_published: true}).exec(
function (err, events) {
if (err) {
reject('an error happened');
throw err;
}else{
resolve(events);
}
});
});
};
Classes.prototype.fn2 = function (item) {
return q.Promise(function(resolve, reject){
resolve(item);
});
};
这是主要代码:
self.items = [{},{},{}]; //some items
self.result = [];
self.items.forEach(function(item,index,array){
if(item.type == 1){
self.fn1(item)
.then(function(result){
self.result.push(result);
})
}
if(item.type == 2){
self.fn2(item)
.then(function(result){
self.result.push(result);
})
}
if(index == array.length-1){
callback(self.result);
}
});
但是没有用。因为 fn1
有一个异步进程,它在 fn2
之后运行。我想要的只是 运行 这些函数顺序执行,甚至其中一个函数具有异步进程。
您可以使用 .reduce
链接承诺。
var promise = q(); // Create a Resolved promise for chaining.
self.items = [{},{},{}]; //some items
self.result = [];
// We put an resolved promise as init value for chaining
self.items.reduce(function(chain, item) {
// Don't do anything if item type is not match
if (item.type !== 1 && item.type !== 2) {
return chain;
}
var targetFunc = null;
if (item.type === 1) {
targetFunc = self.fn1;
} else if (item.type === 2) {
targetFunc = self.fn2;
}
if (targetFunc === null) {
return chain;
}
// Chain the promise and return the last of the chain.
return chain
.then(function(){
return targetFunc(item);
})
.then(function(result){
// This then will get the result from above
// so we put the result to self.result here
self.result.push(result);
});
}, promise).then(function() {
// When all promises are sequentially resolved,
// call the callback with self.resul.
callback(self.result);
});
有一些与下面的烹饪非常相似的东西...但是 fuyushimoya 的速度太快了,尽管我们以不同的方式处理 reduce 的初始化
var promises = self.items.map( function(item) {
if (item.type == 2) {
return self.fn1(item);
}
else if (item.type == 3) {
return self.fn2(item);
}
});
function handler(p) {
return p.then( function(res) {
self.result.push(res);
});
}
promises
.reduce( function(prev, current) {
if (prev) {
return prev.then( function() { handler(current) } )
}
else {
return handler(current)
}
})
.then(function(result) {
callback(null, result);
})
.catch( // error handler);
画出草图。但这样的事情可能会奏效。
UPD:正如评论中提到的那样,诀窍是链接承诺,我在 code snippet here:
中使用了更新版本
var items = [{type:1},{type:2},{type:1}];
var result = [];
var rq = Q();
var ql = rq;
items.forEach(function (it, ix) {
ql = ql.then(function(){
var dp = "fn" + it.type;
return ps[dp]();
})
.then(function(d) {
result.push(d);
});
});
ql.then(function() {
callback(result);
});
在一个Node.js
应用程序中,我想实现这个:
读取数组,取决于项目类型,决定使用 returns 一个 Q
Promise
对象的特定函数。我希望这个过程按顺序运行。
我有这两个承诺:
var q = require('q');
Classes.prototype.fn1 = function (item) {
return q.Promise(function(resolve, reject){
Items.find({item_published: true}).exec(
function (err, events) {
if (err) {
reject('an error happened');
throw err;
}else{
resolve(events);
}
});
});
};
Classes.prototype.fn2 = function (item) {
return q.Promise(function(resolve, reject){
resolve(item);
});
};
这是主要代码:
self.items = [{},{},{}]; //some items
self.result = [];
self.items.forEach(function(item,index,array){
if(item.type == 1){
self.fn1(item)
.then(function(result){
self.result.push(result);
})
}
if(item.type == 2){
self.fn2(item)
.then(function(result){
self.result.push(result);
})
}
if(index == array.length-1){
callback(self.result);
}
});
但是没有用。因为 fn1
有一个异步进程,它在 fn2
之后运行。我想要的只是 运行 这些函数顺序执行,甚至其中一个函数具有异步进程。
您可以使用 .reduce
链接承诺。
var promise = q(); // Create a Resolved promise for chaining.
self.items = [{},{},{}]; //some items
self.result = [];
// We put an resolved promise as init value for chaining
self.items.reduce(function(chain, item) {
// Don't do anything if item type is not match
if (item.type !== 1 && item.type !== 2) {
return chain;
}
var targetFunc = null;
if (item.type === 1) {
targetFunc = self.fn1;
} else if (item.type === 2) {
targetFunc = self.fn2;
}
if (targetFunc === null) {
return chain;
}
// Chain the promise and return the last of the chain.
return chain
.then(function(){
return targetFunc(item);
})
.then(function(result){
// This then will get the result from above
// so we put the result to self.result here
self.result.push(result);
});
}, promise).then(function() {
// When all promises are sequentially resolved,
// call the callback with self.resul.
callback(self.result);
});
有一些与下面的烹饪非常相似的东西...但是 fuyushimoya 的速度太快了,尽管我们以不同的方式处理 reduce 的初始化
var promises = self.items.map( function(item) {
if (item.type == 2) {
return self.fn1(item);
}
else if (item.type == 3) {
return self.fn2(item);
}
});
function handler(p) {
return p.then( function(res) {
self.result.push(res);
});
}
promises
.reduce( function(prev, current) {
if (prev) {
return prev.then( function() { handler(current) } )
}
else {
return handler(current)
}
})
.then(function(result) {
callback(null, result);
})
.catch( // error handler);
画出草图。但这样的事情可能会奏效。
UPD:正如评论中提到的那样,诀窍是链接承诺,我在 code snippet here:
中使用了更新版本 var items = [{type:1},{type:2},{type:1}];
var result = [];
var rq = Q();
var ql = rq;
items.forEach(function (it, ix) {
ql = ql.then(function(){
var dp = "fn" + it.type;
return ps[dp]();
})
.then(function(d) {
result.push(d);
});
});
ql.then(function() {
callback(result);
});