Как я могу получить данные из асинхронного вызова по порядку?

#javascript #asynchronous

Вопрос:

Я делаю http — запросы. Когда запрос выполнен — с обратным вызовом я вызываю другую функцию, в которой данные асинхронного вызова необходимы для создания моей логики. При каждом вызове моего http — запроса lazyLoadData я делаю запросы на новую страницу для данных-так, страница 1 с 25 записями, страница 2 со следующими 25 записями из бэкенда и т. Д…

 getData() {
   this.lazyLoadData(this.testing.bind(this));
   this.lazyLoadData(this.testing.bind(this));
}

lazyLoadData(cb?) {
  // MY HTTP REQUESTS
  let response = axios...
  cb amp;amp; cb();
}


testing(data) {
  // my data arraived
}
 

если я позвоню только один раз

 this.lazyLoadData(this.testing.bind(this));
 

тогда everytjing работает нормально, когда выполняется http-запрос, callback - the testing functions вызывается my, и я получаю данные.

Но когда я звоню, например

два или более раз

 getData() {
   this.lazyLoadData(this.testing.bind(this));
   this.lazyLoadData(this.testing.bind(this));
   this.lazyLoadData(this.testing.bind(this));
   this.lazyLoadData(this.testing.bind(this));
}
 

иногда вызываю 2 — второй this.lazyLoadData(this.testing.bind(this)); выполняется быстрее, чем первый, и я путаю свои данные. Потому что после того, как я делаю http-запрос и получаю, я помещаю эти значения в один глобальный массив, которым заполнена моя таблица.

И данные не в порядке, поэтому иногда массив содержит сначала данные 25 records со страницы 2, затем со страницы 1, страницы 3 и т.д…

Как я могу это предотвратить ?

Комментарии:

1. Используйте asyn-await , для понимания см. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

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

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

4. Спасибо вам за ваш ответ. Но я думал, что с обратным вызовом все то же самое — просто с асинхронным ожиданием код проще.

5. Я хотел знать, почему с обратным вызовом эта проблема не решается ?

Ответ №1:

Да, вы не можете вызывать их последовательно, потому что скорость HTTP-запросов зависит от многих факторов.

Вы можете использовать функцию async/await для решения вашей проблемы.

async ключевое слово всегда возвращает обещание, поэтому вы можете объединить его с await ключевым словом, чтобы указать Javascript подождать, пока ваше обещание будет либо выполнено, либо отклонено.

Поэтому для вашего кода вы могли бы сделать что-то вроде этого

 async function lazyLoadData(){
  //http requests
}
 

в getData вы могли бы просто :

    function getData(){
        // with this, the firstResponse variable will wait for the first call of lazyLoadData to be completed then assigned the value to itself 
        // before the execution move to the second call of the function
        let firstResponse = await lazyLoadData(yourparam)
        let secondResponse = await lazyLoadData(yourparam)
    }
 

Возможно, вы также захотите прочитать о Promise.all, так как это может быть альтернативой моему решению.

Комментарии:

1. Tnx за ваш ответ. В моем случае — обещания или асинхронность/ожидание могут решить мою проблему, верно ? Какая будет разница, если я использую Обещание. повсюду асинхронное ожидание ?

2. на самом деле это зависит от того, как вы хотите, чтобы ваше приложение вело себя, например, хотите ли вы сначала дождаться завершения всех 4 функций, прежде чем назначать их массиву, или вы хотите добавить какой-либо ответ в массив, как только запрос будет завершен? в конце концов, оба подхода верны и похожи друг на друга, но, возможно, если вам нужен более чистый код, вы можете выполнить обещание. весь подход, потому что вам не нужно добавлять ответ несколько раз в массив.

3. асинхронность и ожидание не решили мою проблему. У меня здесь та же проблема