【问题标题】:AngularJS $q.all - wait between http callsAngularJS $q.all - 在 http 调用之间等待
【发布时间】:2017-08-08 09:33:35
【问题描述】:

所以我有一种情况,我需要执行一堆 http 调用,然后在它们完成后,继续进行下一步。

以下是执行此操作且工作正常的代码。

但是,我现在需要在每个 http 调用之间等待几秒钟。有没有办法在我当前的设置中传递超时,或者它会涉及到大量的重构?

如果需要,可以发布更多代码。我尝试将超时配置变量传递给 http 调用,但是,它们仍然会同时被触发。

任何建议都会很棒。

代码

 var allThings = array.map(function(object) {
     var singleThingPromise = getFile(object.id);
     return singleThingPromise;
 });
 $q.all(allThings).then(function() {
     deferred.resolve('Finished');
 }, function(error) {
     deferred.reject(error);
 });

【问题讨论】:

    标签: javascript angularjs http settimeout


    【解决方案1】:

    您可能不想使用$q.all,而是希望在前一个成功时执行顺序调用,并且可能使用$timeout。也许你可以建立一个递归函数。

    像这样..

    function performSequentialCalls (index) {
      if(angular.isUndefined(array[index])) {
        return;
      }
      getFile(array[index].id).then(function() {
        $timeout(function() {
          performSequentialCalls(index + 1)
        }, 1000) // waiting 1 sec after each call
      })
    }
    

    正确注入所需的东西。这假定array 包含带有ids 的对象,您可以使用这些对象执行API 调用。还假设您使用的是$http。如果使用$resource,请相应添加$promise

    希望能有所帮助!

    【讨论】:

    • 干杯!考虑到我上面的设置,我怎么称呼它?
    • @user2085143 您可以在要启动 API 调用的地方调用该函数。而且,如果您看到if 条件与angular.isUndefined...,您可以在那里(return 之前)编写一些代码,这些代码需要在所有调用完成后执行。
    • 谢谢一百万。一旦我得到一些适当的时间,我会尝试一下,如果它工作正常,则标记为正确。
    【解决方案2】:
    function getItemsWithDelay(index) {
      getFile(object[index].id).then(()=>{
       setTimeout(()=>{
         if(index+1 > object.length) { return }
         getItemsWithDelay(index+1)
      }, 5000)
     })
    }
    

    您可以进行顺序调用

    【讨论】:

    • 鉴于我上面的设置,我该如何称呼它?
    【解决方案3】:

    这是在面试中被问到的一个很棒的技巧问题,无论如何我有类似的要求并在互联网上做了一些研究,感谢参考https://codehandbook.org/understanding-settimeout-inside-for-loop-in-javascript

    我能够延迟 angularjs 中的所有 promise 调用,并且同样可以应用于普通的 JS 语法。

    我需要向 TTP API 发送任务,他们要求在每次调用中添加延迟

    _sendTasks: function(taskMeta) {
                var defer = $q.defer();
                var promiseArray = [];
                const delayIncrement = 1000 * 5;
                let delay = 0;
                for (i = 0; i < taskMeta.length; i++) {
                    // using 'let' keyword is VERY IMPORTANT else 'var' will send the same task in all http calls
                    let requestTask = {
                        "action": "SOME_ACTION",
                        "userId": '',
                        "sessionId": '',                        
                    };
                    // new Promise can be replaced with $q - you can try that, I haven't test it although.  
                    promiseArray.push(new Promise(() => setTimeout(() => $http.post(config.API_ROOT_URL + '/' + requestTask.action, requestTask), delay)));
                    delay += delayIncrement;
    
                }
                $q.all(promiseArray).
                then(function(results) {
                        // handle the results and resolve it at the end
                        defer.resolve(allResponses);
                    })
                    .catch(error => {
                        console.log(error);
                        defer.reject("failed to execute");
                    });
                return defer.promise;
            }
    

    注意:: 在 FOR 循环中使用 'let' 关键字非常重要,否则 'var' 将在所有 http 调用中发送相同的任务 - 由于关闭/上下文切换

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-19
      • 2016-05-26
      • 2018-03-13
      • 2014-02-14
      相关资源
      最近更新 更多