Зацикливание функции с обратным вызовом и ожидание результата

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

Я выкинул все ненужные строки кода, чтобы вы могли быстро увидеть, что я хочу сделать.

app.post('/create',  (req,res) => {

  var dataArray = [] 

  req.body.array.forEach((ele) => {

  let blobAdress = ele.link.split('/')[0];
  let extracted = ele.extracted
  let blob = `${blobAdress}/extracted-${extracted}.json`;
  const container =  'test';

  //SHOULD BE EXECUTED FOR EACH ELEMENT OF FOR LOOP  
 
  api.getTextFromBlob(container, blob,  (response, error) => {
   if (error){console.info("Error",error)}
     let jsonResponse = JSON.parse(response);
     console.info(jsonResponse)
     dataArray.push(jsonResponse) // I WANT ALL DATA FROM THE CB IN ONE ARRAY BUNDLED
     })
  })

// RUN THIS PART AFTER FOR LOOP HAS BEEN EXECUTED PROPER

console.info(dataArray) // !ASYNC JS --> DATA ARRAY IS EMPTY BECAUSE datArray IS CONSOLE.LOG BEFORE api.getText EXECTUED
})    
Поведение ключевого слова "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
0
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сначала вам нужно обернуть функцию обратного вызова в объект Promise:

var getTextFromBlobAsPromise = (container, blob) => new Promise((resolve, reject) => {
    api.getTextFromBlob(container, blob, (response, error) => {
        if (error) {
            console.info("Error", error)
            return reject(error); // depends on business
        }
        let jsonResponse = JSON.parse(response);
        console.info(jsonResponse)
        resolve(jsonResponse);
    })
})

Затем вы можете дождаться, пока все промисы будут разрешены, используя функцию Promise.all:

app.post('/create', (req, res) => {

    var promises = [];
    req.body.array.forEach((ele) => {
        let blobAdress = ele.link.split('/')[0];
        let extracted = ele.extracted
        let blob = `${blobAdress}/extracted-${extracted}.json`;
        const container = 'test';

        //SHOULD BE EXECUTED FOR EACH ELEMENT OF FOR LOOP
        promises.push(getTextFromBlobAsPromise(container, blob))   ;
    })

    // RUN THIS PART AFTER FOR LOOP HAS BEEN EXECUTED PROPER
    Promise.all(promises).then(dataArray => {
        console.info(dataArray) // !ASYNC JS --> DATA ARRAY IS EMPTY BECAUSE datArray IS CONSOLE.LOG BEFORE api.getText EXECTUED
    })
})

Спасибо за ваш ответ. Но когда я запускаю его и регистрирую dataArray.length, я получаю 3 разных результата (размер req.body.array) в разных порядках. между 1,2,3. Но мне нужен массив со всеми тремя ответами. Что я могу сделать здесь?

codeBB 22.12.2020 13:49

Promise.all гарантирует, что массив ответов имеет тот же порядок, что и массив обещаний. Таким образом, в этом примере у вас столько одновременных запросов, сколько req.body.array длины. После .then() в dataArray будут все ответы.

Viktor Gusev 22.12.2020 13:54

Однако, если какой-то запрос не будет выполнен, весь Promise.all() будет отклонен. Тогда вам может понадобиться блок .catch(err => {}) сразу после then().

Viktor Gusev 22.12.2020 13:56

Нет, это ненормально. Убедитесь, что Promise.all() запускается только один раз за запрос.

Viktor Gusev 22.12.2020 14:04

У меня также была ошибка во внешнем интерфейсе, где я запускал эту функцию, которая отвечала за все разные длины. Thx 4 вы помогаете.

codeBB 22.12.2020 14:07

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