Разрешить обещания внутри функции setTimeout в цикле for - PullRequest
1 голос
/ 04 июня 2019

Я хочу вызывать web api через некоторый интервал через javascript / angular js 1.x.Я должен сделать это, потому что веб-API, который я вызываю, ограничивает количество вызовов в 300 секунд.

Пожалуйста, найдите ниже код, который я пытаюсь заставить его работать.RecordList - это список объектов, которые мне нужно передать с помощью вызова webapi.setDelay - это функция, которая добавляет задержку к каждому вызову с помощью функции setTimeout.

Внутри функции setTimeout я вызываю webapi, и она успешно создает запись.Я хочу объект или событие или фрагмент кода, который дает мне, что все записи были успешно созданы или нет.Это означает, как узнать, что все обещания внутри функции setTimeout были решены или нет.Я знаю, что Promise.all и $q.all использует, но, похоже, они не работают с функцией setTimeout.Не могли бы вы предложить что-нибудь для этого?

var waitInterval = 300;
var promiseArray = [];

function setDelay(obj, s) {
  setTimeout(function() {
    var SomePromise = $http.post('odataURI', obj).then(function success(result) {
      //resolve(result);
    });
    promiseArray.push(SomePromise);
  }, waitInterval * s);
}
for (var s = 1; s <= RecordList.length; s++) {
  setDelay(RecordList[s - 1], s);
}

Ответы [ 3 ]

2 голосов
/ 04 июня 2019

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

function post(n) {
  return Promise.resolve(n);
}

function setDelay(n, milliseconds) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
       post(n).then(function(res) {
        resolve(res);
      });
    }, milliseconds)
  })
}

function call(list, delay = 1000, index = 0, result = []) {
  setDelay(list[index], delay).then(
    function(res) {
      console.log(res);
      result.push(res);
      if (index == list.length - 1) {
        console.log('Result: ', result); // You can do something here
        return result;
      } else {
        return call(list, delay, index + 1, result);
      }
    }
  ); 
}

var RecordList = [1, 2, 3, 4, 5];
call(RecordList);
1 голос
/ 04 июня 2019

Без рекурсии также возможно,

var waitInterval = 300;
var promiseArray = [];
var tick =0;

function setDelay(obj, s) {
  setTimeout(function() {
    var SomePromise = Promise.resolve(obj);
    SomePromise.then(function success(result) {
      tick ++;
      console.log(result);
      if ( tick === RecordList.length) {
          Promise.all(promiseArray).then((res) => {
            console.log(res);
          });
      }
    });
    promiseArray.push(SomePromise);
  }, waitInterval * s);
}

var RecordList = [1,2,3,4,5];

for (var s = 1; s <= RecordList.length; s++) {
  setDelay(RecordList[s - 1], s);
}
1 голос
/ 04 июня 2019

Вы можете использовать async await для того же

var waitInterval = 300;
var promiseArray = [];

async FunctionOfLoop() {
  var dataMain;
  for (var s = 1; s <= RecordList.length; s++) {
     dataMain = await setDelay(RecordList[s - 1], s); // here you will get the data after api consume successfully.
  }
}

function setDelay(obj, s) {
 return new Promise ((resolve, reject) => {
   setTimeout(function() {
     var SomePromise = $http.post('odataURI', obj).then(function success(result) {
       resolve(result);
     });
    }, waitInterval * s);
 }); 
}

Надеюсь, это поможет вам.

...