Node js обещание внутри для l oop всегда печатает обещание {<pending>} - PullRequest
0 голосов
/ 29 апреля 2020

Я пытаюсь выполнить обещание внутри-l oop в node js. В моем коде у меня есть для l oop, в котором я вызываю функцию findincollection, которая возвращает обещание. Затем я помещаю sh данные в массив finalresult и разрешаю их после завершения l oop. Но проблема, с которой я сталкиваюсь, состоит в том, что это не решает полные данные. Выполнение for l oop заканчивается до того, как все обещания будут разрешены. Строка console.log(p1); всегда печатает Promise {}, но в конечном итоге она разрешается, как вы можете видеть в моем коде в выражении p1.then(), я получаю данные по одному. Но массив finalresult разрешается слишком рано. Я также хочу знать, почему я всегда получаю Обещание {}, даже когда обещания все еще выполняются в конце концов. Пожалуйста, посмотрите на мой код ниже:

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');
            });
        }
    });
}

Я не могу понять, как заставить l oop ждать, пока все обещания будут разрешены, или сделать код синхронным, а затем разрешать только массив finalresult? Как мне это сделать?

1 Ответ

1 голос
/ 29 апреля 2020

Что вам нужно здесь, это Promise.all(). Он возвращает новое обещание, которое разрешается после разрешения всех пройденных обещаний.

Вы можете попробовать что-то похожее на:

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

Я вижу, вы закрываете клиента внутри каждого обещания, и это Клиент не является локальной переменной. Поэтому я думаю, что вы должны закрыть его после того, как все ваши обещания будут выполнены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...