Возникла проблема с порядком операций в функции node.js

У меня есть функция, которую я хотел бы использовать для опроса исторических данных, начиная с начала торговли Ethereum на бирже gdax до текущей. Я хочу, чтобы код опрашивал 100 результатов (максимально допустимое за раз), вставлял результаты в mongodb, добавлял 100, затем повторял до тех пор, пока не получу все исторические данные. Однако то, что я написал, выполняется в другом порядке. Сначала он суммирует все числа в for, затем выполняет все запросы http authedclient (хотя он правильно использует переменную, добавляющую 100 к каждому запросу), затем сбрасывает все данные в mongodb. Проблема у меня к тому времени, когда данные вставляются в клиент mongodb, соединение закрывается. Как я могу заставить его выполнять каждую операцию в том порядке, в котором я хочу? Pastebin размещен ниже. Обратите внимание, что код, который я использую, значительно изменился, чтобы учесть другие ошибки, изменил цикл вставки на insertMany, но я могу правильно интегрировать предложения, если кто-нибудь может помочь. Заранее спасибо.
https://pastebin.com/1BHi9RQV

var i = 100;

for (; i < 18750000; ) {

    publicClient.getProductTrades({ after: i }, function (err, response, data) {

        if (err) {

            console.log(err);

            return;

        }

        MongoClient.connect(url, function (err, db) {

            if (err) {

                console.log(err);

                return;

            }

            var myobj = { data };

            for (item in data) {

                db.collection("EthTest").insertOne(data[item], function (err, res) {

                    if (err) {

                        console.log(err);

                        return;

                    }

                });

                console.log(data[item].trade_id);

            }

            db.close();

        });

    });

    i = i + 100;

};

Также загружено приложение стека, чтобы правильно разместить ссылку и код. Мобильный сайт не позволил мне сделать это. Сожалею!

1 ответ

Не ставь db.close(); в вашем for петля. Называйте его только после того, как все ваши вставки завершены.

Если этот порядок действительно важен (получить 100 результатов, сохранить их и т. Д.), Я предлагаю вам разбить этот код на 2 функции, которые вызывают друг друга. Что-то вроде того:

var i = 100;
var mongo;

function getData() {
    publicClient.getProductTrades({ after: i }, function (err, response, data) {
        if (err) {
            console.log(err);
            return;
        }

        i = i + 100;
        saveData(data);
    });
}

function saveData(data) {

    var keys = Object.keys(data);

    // loop through the data
    for (j = 0, end = keys.length; j < end; j++) {
        db.collection("EthTest").insertOne(data[item], function (err, res) {
            if (err) {
                console.log(err);
                return;
            }

            console.log(data[item].trade_id);

            if (keys[j] === keys[keys.length-1]) {
                // last item in data was inserted
                if (i < 18750000) {
                    // get the next 100 results if there's any
                    getData();
                } else {
                    mongo.close();
                }
            }
        });
    };
}


MongoClient.connect(url, function (err, db) {
    if (err) {
        console.log(err);
        return;
    }

    mongo = db;
    getData();
});

Или, конечно, я не могу проверить это для вас, но я надеюсь, что вы поняли идею.

Другой вариант - разделить ваши 2 асинхронных вызова. Пусть первый цикл получит все данные (по 100 за раз), сохранит их в массиве и, как только это будет сделано, перебирает этот массив и вставляет данные в Mongo.

Другие вопросы по тегам