您如何将函数调用推送到数组而不在 Node JS 中调用它们以使用 Q?
How do you push function calls onto an array without calling them in Node JS for using Q?
我想创建一个函数数组来动态调用,稍后将在 Q.all([]) promise 调用中使用。
例如;
//data is previously generated
var promiseArray = [];
for (var i = 0; i < data.length; i++){
promiseArray.push(functionCall(data[i]))
}
Q.all(promiseArray).then(function(){
//Do something
})
如何在 Q.all 语句之前不调用函数就推送到数组?我不想在 for 循环中调用它,因为它不会捕获任何错误并且我无法进一步处理响应。
编辑:
所以为了澄清我的问题(因为我认为我没有像我应该的那样清楚),这是静态数据长度为 3 的解决方案;
//data is previously generated
var data = [12432432,4324322392,433324323];
//Each function call can happen in parallel or series as its an external POST to an API
//I'm not bothered about speed for this application (as its low throughput) and can wait a few seconds for each
// response
//FunctionCall returns a promise
functionCall(data[0]).then(function(){
//Log success / failure to mongo
});
functionCall(data[1]).then(function(){
//Log success / failure to mongo
});
functionCall(data[2]).then(function(){
//Log success / failure to mongo
});
//OR
functionCall(data[0]).then(function(){
//Log success/failure to mongo
functionCall(data[1]).then(function(){
//Log success/failure to mongo
functionCall(data[2]).then(function(){
//Log success/failure to mongo
});
});
});
但是直到运行时我才知道数据的长度
我建议为此使用 Promise.mapSeries 或异步库,因为它很容易捕获错误。如果回调中有数据库调用,使用 for 循环循环的另一件事似乎不是好方法,因为这可能会刷新对数据库的调用并且 node.js 可能有内存问题或 node.js 将无法处理任何其他请求,因为它将忙于处理 for 循环中的请求。因此,运行 串行循环或限制一次并行执行的数量总是好的。
请看下面的例子
This will run Array serially one at a time when 1st one completes execution next will be called
async.eachOfSeries(data, function(dataInstance, key, next) {
functionCall(dataInstance).then(function(){
next();
}).catch(funtion(err){
next(err);
})
}, function() {
//iteration completed
});
或
async.eachOfSeries(data, function(dataInstance, key, next) {
functionCall(dataInstance, function(err , result){
if(err)
{
console.log(err);
next(err);
}
else
next();
});
}, function() {
//iteration completed
});
如果我没理解错的话,你想调用 functionCall
获取一组项目,并在 functionCall
编辑的所有承诺 return 完成后让 Q.all 解决已完成 无论他们是解决还是拒绝 - 如果您不关心结果(因为您在代码中似乎不关心)只需处理您推送的承诺中的拒绝 - 即
var promiseArray = [];
for (var i = 0; i < data.length; i++) {
promiseArray.push(functionCall(data[i]).then(function(result) {
// log success
return logToMongoFunction(result);
}, function(error) {
// log failure
return logToMongoFunction(error);
}).catch(function(error) {
// catch and ignore any error thrown in either logToMongoFunction above
return;
}));
}
Q.all(promiseArray).then(function () {
//Do something
});
Note: the above can be simplified to
Q.all(data.map(function (item) {
return functionCall(item).then(function(result) {
// log success
return logToMongoFunction(result);
}, function(error) {
// log failure
return logToMongoFunction(error);
}).catch(function(error) {
// catch and ignore any error thrown in either logToMongoFunction above
return;
});
})).then(function() {
//Do something
});
the edited question suggests you can perform the actions in series also - in series it would be
data.reduce(function(promise, item) {
return promise.then(function() {
return functionCall(item).then(function(result) {
// log success
return logToMongoFunction(result);
}, function(error) {
// log failure
return logToMongoFunction(error);
}).catch(function(error) {
// catch and ignore any error thrown in either logToMongoFunction above
return;
});
});
}, Promise.resolve()).then(function() {
// all done
});
而不是 Promise.resolve()
你可以使用任何 Q
作为创建已解决承诺的等价物
logToMongoFunction
将登录到 mongo 并且需要 return 一个承诺 如果 你需要等待它完成才能处理下一个数据项。如果您不需要等待 mongo 日志记录完成,那么该函数就不需要 return 承诺
我想创建一个函数数组来动态调用,稍后将在 Q.all([]) promise 调用中使用。
例如;
//data is previously generated
var promiseArray = [];
for (var i = 0; i < data.length; i++){
promiseArray.push(functionCall(data[i]))
}
Q.all(promiseArray).then(function(){
//Do something
})
如何在 Q.all 语句之前不调用函数就推送到数组?我不想在 for 循环中调用它,因为它不会捕获任何错误并且我无法进一步处理响应。
编辑:
所以为了澄清我的问题(因为我认为我没有像我应该的那样清楚),这是静态数据长度为 3 的解决方案;
//data is previously generated
var data = [12432432,4324322392,433324323];
//Each function call can happen in parallel or series as its an external POST to an API
//I'm not bothered about speed for this application (as its low throughput) and can wait a few seconds for each
// response
//FunctionCall returns a promise
functionCall(data[0]).then(function(){
//Log success / failure to mongo
});
functionCall(data[1]).then(function(){
//Log success / failure to mongo
});
functionCall(data[2]).then(function(){
//Log success / failure to mongo
});
//OR
functionCall(data[0]).then(function(){
//Log success/failure to mongo
functionCall(data[1]).then(function(){
//Log success/failure to mongo
functionCall(data[2]).then(function(){
//Log success/failure to mongo
});
});
});
但是直到运行时我才知道数据的长度
我建议为此使用 Promise.mapSeries 或异步库,因为它很容易捕获错误。如果回调中有数据库调用,使用 for 循环循环的另一件事似乎不是好方法,因为这可能会刷新对数据库的调用并且 node.js 可能有内存问题或 node.js 将无法处理任何其他请求,因为它将忙于处理 for 循环中的请求。因此,运行 串行循环或限制一次并行执行的数量总是好的。
请看下面的例子
This will run Array serially one at a time when 1st one completes execution next will be called
async.eachOfSeries(data, function(dataInstance, key, next) {
functionCall(dataInstance).then(function(){
next();
}).catch(funtion(err){
next(err);
})
}, function() {
//iteration completed
});
或
async.eachOfSeries(data, function(dataInstance, key, next) {
functionCall(dataInstance, function(err , result){
if(err)
{
console.log(err);
next(err);
}
else
next();
});
}, function() {
//iteration completed
});
如果我没理解错的话,你想调用 functionCall
获取一组项目,并在 functionCall
编辑的所有承诺 return 完成后让 Q.all 解决已完成 无论他们是解决还是拒绝 - 如果您不关心结果(因为您在代码中似乎不关心)只需处理您推送的承诺中的拒绝 - 即
var promiseArray = [];
for (var i = 0; i < data.length; i++) {
promiseArray.push(functionCall(data[i]).then(function(result) {
// log success
return logToMongoFunction(result);
}, function(error) {
// log failure
return logToMongoFunction(error);
}).catch(function(error) {
// catch and ignore any error thrown in either logToMongoFunction above
return;
}));
}
Q.all(promiseArray).then(function () {
//Do something
});
Note: the above can be simplified to
Q.all(data.map(function (item) {
return functionCall(item).then(function(result) {
// log success
return logToMongoFunction(result);
}, function(error) {
// log failure
return logToMongoFunction(error);
}).catch(function(error) {
// catch and ignore any error thrown in either logToMongoFunction above
return;
});
})).then(function() {
//Do something
});
the edited question suggests you can perform the actions in series also - in series it would be
data.reduce(function(promise, item) {
return promise.then(function() {
return functionCall(item).then(function(result) {
// log success
return logToMongoFunction(result);
}, function(error) {
// log failure
return logToMongoFunction(error);
}).catch(function(error) {
// catch and ignore any error thrown in either logToMongoFunction above
return;
});
});
}, Promise.resolve()).then(function() {
// all done
});
而不是 Promise.resolve()
你可以使用任何 Q
作为创建已解决承诺的等价物
logToMongoFunction
将登录到 mongo 并且需要 return 一个承诺 如果 你需要等待它完成才能处理下一个数据项。如果您不需要等待 mongo 日志记录完成,那么该函数就不需要 return 承诺