Возникла проблема с порядком операций в функции 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.