insertMany внутри setTimeout и для цикла с асинхронными функциями - PullRequest
0 голосов
/ 11 октября 2018

Я пытаюсь написать следующий код и заставить его работать синхронно, но единственная проблема в том, что он корректно работает с console.log, который печатает каждый элемент в массиве с задержкой в ​​1 секунду, но не работает сследующая структура:

for (let i = 0; i < array.length; i++) {
    setTimeout(function () {
        1.http request via rp or request.get (I receive a huge data array)
        2. .map results 
        3.insert to Mongo via mongoose 
     }
}

на данный момент у меня есть следующий код внутри:

request.get({url: array[i].url}), function (error, body) {
    body.map(element => {
        //do stuff, it works fine
     });
     collection.insertMany(body, function (err, docs) {
         //#justloggerthings
     }

Или у меня почти такая же версия с rp вместо request.get По умолчаниюУ меня mongoose.Promise = global.Promise;

Почему это вызывает проблемы?Потому что body.length - это очень большой набор данных, который потребляет много оперативной памяти.(Теперь представьте 20+ массивов с insertMany)

Итак, Монго пытается insertMany сразу ответить на все ответы на запрос (когда они будут готовы, без задержки 1000 с).На самом деле, именно поэтому я выбираю request вместо rp (request-promise), но это выглядит асинхронно.Поэтому я должен выбрать другой http get модуль из npm и переключиться на него.И не беспокоиться об этом?

Или я должен обернуть эти операции, чтобы пообещать ||сделал асинхронную функцию и каждый раз вызывал ее в цикле (например, 1000 с), когда все правильно завершено.В этом случае единственное, что я нашел актуальным в StackOverflow, это:

Как вставить данные в монго синхронно (Nodejs, Express)

Бит, это немного устарело,Так есть идеи?

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Фактический код, который решает мою проблему:

async function test (name, url, lastModified) {
    try {
        const response = await rp({uri: url, json: true});
        response.map(async (element) => {
            if (element.buyout > 0) {
                element.price = (element.buyout / element.quantity);
            }
            element.lastModified = lastModified
        });
        return collection.insertMany(response);
    } catch (err) {
        console.error(err)
    }
}

async function addAsync() {
    const z = await test();
    console.log(z);
}

addAsync();
0 голосов
/ 11 октября 2018

Ну, у меня нет вашего фактического кода, поэтому я напишу в псевдокоде, что вы можете сделать.

const chunkArray = (array, chunkSize) => {
    let i,j,chunks = [];
    for (i = 0, j = array.length; i < j; i += chunkSize) {
        chunks.push(array.slice(i, i + chunkSize));
    }
    return chunks;
}

for (let i = 0; i < array.length; i++) {
    let bigArray = await request('your data url');
    // do some mapping or whatever
    // then break your large array into smaller chunks
    let chunks = chunkArray(bigArray, 10);
    let j;
    for (j = 0; j < chunks.length; j++) {
        await collection.insertMany(chunks[j]);
    }

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