Как справиться с асинхронностью в Nodejs?

У меня есть случай, когда у меня есть много данных, которые мне нужно отсортировать по разным сегментам. Если уже существует корзина для определенного типа данных, вставьте ее туда, но если обнаруженный тип данных новый, мне нужно создать для него новую корзину, которая требует запроса БД. Теоретически это работает нормально. Но у меня проблема в том, что запросы к БД должны выполняться до продолжения цикла, чтобы будущие данные можно было вставить в это ведро. Как я могу приостановить цикл до завершения функции?

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

Обновлено: добавлен код с обещаниями, как предлагали люди. На самом деле он работает хорошо, но просто останавливается на точке данных 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();
            }

        })       
    }
}

Можете ли вы опубликовать текущий код, который работает должным образом (кроме ошибки), возможно, мы найдем способ исправить это?

CertainPerformance 14.06.2018 22:47

Сделайте это async, затем await своим творением. И обычно вы не получаете StackOverflow с обратными вызовами. Пожалуйста, покажите нам свой код.

Jonas Wilms 14.06.2018 22:48

Какую именно ошибку вы получаете? Как было предложено @CertainPerformance, опубликуйте текущий код. Вы должны использовать библиотеку для выполнения запросов, которые либо возвращают обещание, либо принимают функцию обратного вызова, с которой вы должны продолжить выполнение вашего кода в асинхронном режиме.

Alessandro 14.06.2018 22:54

Я попробовал с обещаниями, как предлагали люди, и у меня возникла странная проблема. Добавлен код по запросу.

Ashton Spina 14.06.2018 23:36
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
114
3

Ответы 3

Вы пробовали async await. Для асинхронных функций вы можете дождаться обещания возврата в вызовах базы данных вашего дела, и как только это разрешится, вы можете перейти к следующему. Пожалуйста, просмотрите и другую ссылку, это поможет вашему делу. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

Спасибо, я пробовал асинхронные функции, работал хорошо, но возникла странная проблема.

Ashton Spina 14.06.2018 23:49

Если я правильно понимаю вашу проблему, я думаю, вы могли бы просто решить ее с помощью Promises? И, возможно, объедините его с интервалом, который вы можете установить / сбросить, чтобы контролировать, когда вы хотите, чтобы ваш цикл останавливался / продолжался, если вы хотите периодически запускать материал.


ЕСЛИ не знаком с обещаниями, я бы посоветовал проверить:

Спасибо, я попробовал Promises, работал хорошо, но возникла странная проблема.

Ashton Spina 14.06.2018 23:49

Что случилось? Может быть, мы сможем отладить это для вас.

heldic 14.06.2018 23:53

Что касается паузы в цикле, если у вас 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();

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