[英]How to wait for each iteration in for loop and return response as API response in nodeJS
我正在使用for循环遍历元素数组,并在for循环内使用不同的参数调用相同的函数。 这是我的代码:
exports.listTopSongs = function(query) {
return new Promise(function(resolve, reject) {
var str = query.split(","), category,
for(var i=0; i<str.length; i++) {
sampleFn(str[i], 'sample', resolve, reject);
}
});
};
function sampleFn(lang, cat, resolve, reject) {
client.on("error", function (err) {
console.log(err);
var err = new Error('Exception in redis client connection')
reject(err);
});
client.keys(lang, function (err, keys){
if (err) return console.log(err);
if(keys.length != 0) {
client.hgetall(keys, function (error, value) {
var objects = Object.keys(value);
result['title'] = lang;
result[cat] = [];
var x =0;
for(x; x<objects.length; x++) {
var val = objects[x];
User.findAll({attributes: ['X', 'Y', 'Z'],
where: {
A: val
}
}).then(data => {
if(data != null) {
//some actions with data and stored it seperately in a Json array
if(result[cat].length == objects.length) {
resolve(result);
}
} else {
console.log(""+cat+" is not avilable for this value "+data.dataValues['X']);
}
});
}
});
});
}
在这里,它不会等待第一次迭代的完成。 它只是在完成第一个迭代功能之前异步运行。 我需要将结果返回为结果:[{1,2},{3,4}]。 但它可以无缝运行,并在完成所有操作之前返回空或仅返回一个对象。 如何解决。
我使用了node-async-loop。 但是它使用了下一个,并且在使用该程序包时我无法发送参数。 请帮我
异步提供了允许的控制流方法。
使用async.each :
async.each(openFiles, function(file, callback) {
// Perform operation on file here.
console.log('Processing file ' + file);
if( file.length > 32 ) {
console.log('This file name is too long');
callback('File name too long');
} else {
// Do work to process file here
console.log('File processed');
callback();
}
}, function(err) {
// if any of the file processing produced an error, err would equal that error
if( err ) {
// One of the iterations produced an error.
// All processing will now stop.
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
如果您不想使用库,则可以自己编写代码。 这也将很有启发性。 我接受了您的问题,并编写了一个虚拟的异步循环:
function listTopSongs(query) { return new Promise(async(resolve, reject) => { //add async here in order to do asynchronous calls const str = query.split(",") //str is const, and the other variable was not used anyway for( let i = 0;i < str.length; i++) { const planet = await sampleFn(str[i], 'sample', resolve, reject) console.log(planet) } }); }; function sampleFn(a, b, c, d) { return fetch(`https://swapi.co/api/planets/${a}/`) .then(r => r.json()) .then(rjson => (a + " : " + rjson.name)) } listTopSongs("1,2,3,4,5,6,7,8,9")
我使用了一些虚拟的《星球大战》 API伪造了长期承诺,但它应该与您的sampleFn一起使用。 请注意,如果您像示例中那样进行网络通话,这将非常非常慢。
编辑:我运行了您的代码,我发现有一些错误:您的承诺中没有任何解决方法,因此它是不可行的( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ Global_Objects / Promise / resolve 参见thenable )
这是一个完整的代码。 好的部分:不需要库,没有依赖项。
//for node.js, use node-fetch : //const fetch = require("node-fetch") function listTopSongs(query) { return new Promise(async(resolve, reject) => { //add async here in order to do asynchronous calls const str = query.split(",") //str is const, and the other variable was not used anyway const planets = [] for (let i = 0; i < str.length; i++) { const planet = await sampleFn(i + 1, str[i], resolve, reject) planets[i] = planet console.log(planet) } resolve(planets) }); }; function sampleFn(a, b, c, d) { return fetch(`https://swapi.co/api/planets/${a}/`) .then(r => r.json()) .then(rjson => (a + b + " : " + rjson.name)) } listTopSongs("a,b,c,d").then(planets => console.log(planets))
由于您正在使用诺言,因此您可以执行以下操作
exports.listTopSongs = function(query) {
return Promise.resolve(true).then(function(){
var str = query.split(",");
var promises = str.map(function(s){
return sampleFn(str[i], 'sample');
});
return Promise.all(promises);
}).then(function(results){
//whatever you want to do with the result
});
};
为此,您必须将sampleFn更改为不依赖于外部解析和拒绝函数。 我看不到使用外部解决和拒绝的原因。 为什么不使用Promise.Resolve,Promise.Reject ;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.