Node js promise inside for loop always prints Promise { <pending> }

自闭症网瘾萝莉.ら 提交于 2020-05-24 06:10:11

问题


I'm trying to resolve a promise inside a for-loop in node js. In my code, I have a for loop in which I call a function findincollection that returns a promise. Then I push the data to finalresult array and resolve it once the for loop completes. But the issue I'm facing is it doesn't resolve the complete data. The for loop execution is getting finished before all the promises are resolved. The line console.log(p1); always prints Promise { } but it eventually gets resolved as you can see in my code in the p1.then() statement, I do get the data one by one. But the finalresult array resolves too early. I also want to know why I always get Promise { } even when the promises are still getting resolved eventually. Please have a look at my code below :

var mob = [123, 456, 789];
var list = [1, 2, 3, 4, 5, 6, 7, 8];
var res = [];
var finalresult = [];
for (y = 0; y < list.length; y++) {
    const p1 = findincollection(list[y], mob, savetofile);
    console.log(p1); //always prints Promise { <pending> } 8 times
    p1.then(function(dt) {
        finalresult.push(dt); //pushes all 3 objects one by one
        console.log(dt); //prints 3 objects one by one
        client.close();
        if (y == (collist.length)) { //check if the loop has reached the last index
            resolve(finalresult); //resolves the finalresult array with 1 object only instead of 3. I want this part to resolve the complete finalresult array i.e with all 3 objects.
        }
    });
}

const findincollection = function(index, mob, save) {
    return new Promise((resolve, reject) => {
        MongoClient.connect(url, function(err, client) {
            assert.equal(null, err);
            const db = client.db(dbName);
            const collection = db.collection(col);
            collection.find({ 'Numbers': { $in: mob } }).toArray(function(err, docs) {
                const c = save(index, docs);
                c.then(function(m) {
                    console.log(m); //print's Saved 3 times as the mob array length is 3
                    client.close();
                    return resolve(res);
                })
            });
        });
    });
}

const save = function(index, data) {
    return new Promise((resolve, reject) => {
        if (data.length > 0) {
            for (var k = 0; k < data.length; k++) {
                res.push(data[k]);
            }
            fs.appendFile('textlogs/' + index + '.txt', data, function(err) {
                if (err) throw err;
                resolve('Saved');
            });
        }
    });
}

I'm not able to figure out how to make the loop wait until all the promises are resolved or make the code synchronous and then only resolve the finalresult array? How do I do it?


回答1:


What you need here is Promise.all(). It returns a new promise, which gets resolved once all passed promises get resolved.

You can try something similar to:

var promises = [];

for (y = 0; y < list.length; y++) {
    promises.push(findincollection(list[y], mob, savetofile));
}

Promise.all(promises)
   .then(dt => {
       finalresult.push(dt); //pushes all 3 objects one by one
       console.log(dt); //prints 3 objects one by one
       client.close();
       if (y == (collist.length)) { 
           resolve(finalresult);
       }
   }); // <-- this will be raised once all your promises are resolved

I see you're closing client inside each promise and this client is not a local variable. So I think you should be closing it after all your promises are completed.



来源:https://stackoverflow.com/questions/61493692/node-js-promise-inside-for-loop-always-prints-promise-pending

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!