【问题标题】:Resolve promises inside setTimeout function in for-loop在 for 循环中解决 setTimeout 函数内的承诺
【发布时间】:2019-06-04 09:06:51
【问题描述】:

我想通过 javascript/angular js 1.x 每隔一段时间调用 web api。我必须这样做,因为我正在调用的 web 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);
}

【问题讨论】:

  • ' 是在 odataURI' 错字吗?
  • 是的,这是拼写错误,我已经编辑过了。
  • 他们似乎没有使用 setTimeout 函数”。当然 setTimeout 不会返回 Promise。你试过Promise.all(promiseArray) 吗?
  • 实际上promiseArray 只包含最后插入的记录的promise。它不会保留所有对象。
  • 也欢迎任何其他符合此要求的代码。

标签: javascript angularjs http promise settimeout


【解决方案1】:

您可以使用递归函数在完成后运行下一个 Promise。

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);

【讨论】:

    【解决方案2】:

    你也可以使用asyncawait

    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);
     }); 
    }
    

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      没有递归也是可能的,

      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);
      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-11
        • 2018-03-13
        • 1970-01-01
        • 2015-11-13
        • 2015-05-05
        • 2021-08-03
        • 2023-03-17
        相关资源
        最近更新 更多