У меня есть случай, когда у меня есть много данных, которые мне нужно отсортировать по разным сегментам. Если уже существует корзина для определенного типа данных, вставьте ее туда, но если обнаруженный тип данных новый, мне нужно создать для него новую корзину, которая требует запроса БД. Теоретически это работает нормально. Но у меня проблема в том, что запросы к БД должны выполняться до продолжения цикла, чтобы будущие данные можно было вставить в это ведро. Как я могу приостановить цикл до завершения функции?
Я пробовал цикл и подход обратного вызова, и я получаю поток управления, который ищу, но данные слишком велики, и я переполняю стек. Есть ли другой способ решить эту проблему?
Обновлено: добавлен код с обещаниями, как предлагали люди. На самом деле он работает хорошо, но просто останавливается на точке данных 8428. Насколько я могу судить, эта точка данных не является особенной, и все сегменты были созданы в этот момент, поэтому новый сегмент не создается. Это просто останавливается. Любые идеи? Может быть, это как я звоню next (), и мне не хватает дела?
async function sortData(data, images, i) {
let uuidList = [];
//This loop will wait for each next() to pass the next iteration
for (var j = 0; j < data.length; ++j) {
await new Promise(next=> {
let pos = uuidList.map(function(e) { return e.uuid; }).indexOf(data[j].uuid);
if (pos < 0){
Instance_Type.findInstance(data[j]._instance_type, function(err, instance){
/* add new bucket here */
if (itemsProcessed == images.length) {
processBuckets(uuidList, threshold, function(){
console.info("Bucket finished");
dataPackage.push({
imageName: images[i].name,
uuidList: uuidList,
});
++itemsProcessed;
if (itemsProcessed == images.length){
console.info("Rendering!");
res.render('data', {
dataPackage: dataPackage
});
}
});
}
next();
});
} else {
/*push to existing bucket here*/
if (itemsProcessed == images.length) {
processBuckets(uuidList, threshold, function(){
console.info("Bucket finished");
dataPackage.push({
imageName: images[i].name,
uuidList: uuidList,
});
++itemsProcessed;
console.info(itemsProcessed);
if (itemsProcessed == images.length){
console.info("Rendering!");
res.render('data', {
dataPackage: dataPackage
});
}
});
}
next();
}
})
}
}
Сделайте это async, затем await своим творением. И обычно вы не получаете StackOverflow с обратными вызовами. Пожалуйста, покажите нам свой код.
Какую именно ошибку вы получаете? Как было предложено @CertainPerformance, опубликуйте текущий код. Вы должны использовать библиотеку для выполнения запросов, которые либо возвращают обещание, либо принимают функцию обратного вызова, с которой вы должны продолжить выполнение вашего кода в асинхронном режиме.
Я попробовал с обещаниями, как предлагали люди, и у меня возникла странная проблема. Добавлен код по запросу.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы пробовали async await. Для асинхронных функций вы можете дождаться обещания возврата в вызовах базы данных вашего дела, и как только это разрешится, вы можете перейти к следующему. Пожалуйста, просмотрите и другую ссылку, это поможет вашему делу. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
Спасибо, я пробовал асинхронные функции, работал хорошо, но возникла странная проблема.
Если я правильно понимаю вашу проблему, я думаю, вы могли бы просто решить ее с помощью Promises? И, возможно, объедините его с интервалом, который вы можете установить / сбросить, чтобы контролировать, когда вы хотите, чтобы ваш цикл останавливался / продолжался, если вы хотите периодически запускать материал.
ЕСЛИ не знаком с обещаниями, я бы посоветовал проверить:
Спасибо, я попробовал Promises, работал хорошо, но возникла странная проблема.
Что случилось? Может быть, мы сможем отладить это для вас.
Что касается паузы в цикле, если у вас Node 7.6 или выше.
let myData = ["a", "b", "c"];
//TODO: Use try catch
async function findMyBucket() {
for (let x = 0; x < myData.length; x += 1) {
var resp = await checkCreateAndInsertInBucket(myData[x]); //Loop pauses
console.info(resp);
}
}
function checkCreateAndInsertInBucket(data) {
return new Promise((resolve, reject) => {
//DB Logic here with a promise or callback
resolve(true); //or reject
});
}
findMyBucket();
Можете ли вы опубликовать текущий код, который работает должным образом (кроме ошибки), возможно, мы найдем способ исправить это?