Сделайте что-нибудь после завершения всех асинхронных вложенных вызовов базы данных $ .each - PullRequest
0 голосов
/ 19 февраля 2020

Я пытаюсь запустить функцию после 1) все циклы завершены и 2) все вызовы базы данных в этих циклах завершены.

Все функции вызова базы данных (segmentDatabaseCall и stepDatabaseCall) принимают некоторые аргументы, разрешают Обещание и отправляют данные после завершения вызова. Это (очень) упрощенная версия моего кода:

let localData = {}

segmentDatabaseCall(argument) // Call the database
.then(segmentResult => { // Returns trip segments (array of objects)

  $.each(segmentResult, (segmentIndex, segmentValue) => { // For each trip segment...

    localData['something'] = segmentValue.something // Add some data to local data

    stepDatabaseCall(segmentValue.segment_id) // Call the database once per trip segment...
    .then(stepResult => { // Returns trip steps (array of objects)

      $.each(stepResult, (stepIndex, stepValue) => { // For each trip step...

        localData['something'][i]['something_else'] = stepValue.something_else // Add some data to local data

        // THIS DOESN'T WORK
        const segsDone = segmentIndex >= segmentResult.length - 1;
        const stepsDone = stepIndex >= stepResult.length - 1;
        if (segsDone && stepsDone) {
          // This if statement runs before all calls are finished 1 out of 3 times roughly
        }
      })
    })
  })
})

Вызов базы данных:

function databaseCall (argument) {
    return new Promise((resolve, reject) => {
        $.ajax({
          url: $phpUrl,
          type: 'post',
            data: {
              'argument': argument      
            }
        })
        .done (function (data) {
            var resultJson = JSON.parse(data)
            resolve(resultJson)
        })
        .fail (function (error) {
            reject(error)
        })
    })
}

Я пытался использовать ответ здесь , но это выполняется до завершения всех вызовов 1 в 3 раза. Я, должно быть, пропускаю какой-то счетчик там?

Я также думаю, что есть способ сделать это, используя карты Promise, но я не могу разобраться с этим.

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

В Rx js есть нечто, называемое forkJoin. Насколько я понимаю ваш вопрос, вы можете использовать его для своей реализации.

forkJoin(
      this._myService.makeRequest('Request One', 2000),
      this._myService.makeRequest('Request Two', 1000),
      this._myService.makeRequest('Request Three', 3000)
    )
    .subscribe(([res1, res2, res3]) => {
      this.propOne = res1;
      this.propTwo = res2;
      this.propThree = res3;
    });

читать больше здесь .

0 голосов
/ 19 февраля 2020

Видя, что вы уже используете JQuery, вы можете обернуть все свои асинхронные вызовы с помощью функции $.when.

Это позволит вам связать воедино все свои обещания и управлять выполнением всех обещания с одной .done() функцией.

https://api.jquery.com/jQuery.when/

С веб-сайта JQuery:

$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) ).done(function( a1, a2 ) {
  // a1 and a2 are arguments resolved for the page1 and page2 ajax requests, respectively.
  // Each argument is an array with the following structure: [ data, statusText, jqXHR ]
  var data = a1[ 0 ] + a2[ 0 ]; // a1[ 0 ] = "Whip", a2[ 0 ] = " It"
  if ( /Whip It/.test( data ) ) {
    alert( "We got what we came for!" );
  }
});
...