Javascript超时循环将多行保存到Parse.com

时间:2015-05-31 15:45:52

标签: javascript json loops parse-platform timeout

我在parse.com云代码中编写了一个beforeSave脚本。我想保存所有结果以进行解析,因此它们都会运行此脚本并在保存之前修改其数据。

我已通过以下方式解决了这个问题。

  1. 从Parse.com仪表板导出JSON。

  2. 在我的应用中将其用作本地JSON并运行以下循环:

  3. CODE:

    $http.get('data/full_data.json')
       .then(function(res) {
      var counter = 0;
          for (var i = 0; i < res.data.results.length; i++) {
              setDelay(counter);
              saveToParse(res.data.results[i]);
              counter ++
          };
        }
      });
    
    function setDelay(i) {
      setTimeout(function() {
        console.log(i);
      }, 1000);
    }
    
    function saveToParse(exercise) {
    
      console.log(exercise);
      ParseFactory.provider('Exercises/').edit(exercise.objectId, exercise).success(function(data) {
    
      }).error(function(response) {
        $ionicLoading.hide();
        $rootScope.$emit('errorEvent', {
          "message": "Please check your connection",
          "errorObject": response
        });
      });
    }
    

    我一直在尝试使用超时功能,因此我不会超过Parse.com上允许的API调用次数。

    我的问题是我的所有API调用都已完成,然后在暂停1秒后,它会在最后快速运行超时。

    如何确保每次循环迭代在再次循环之前都会超时。

    答案在前50秒内完美运行,然后缓慢工作......请参阅此屏幕抓取网络活动。

    network trace

1 个答案:

答案 0 :(得分:1)

您可以让所有功能都返回承诺。并且要使循环异步,您将其转换为递归“循环”。

$http.get('data/full_data.json')
     .then(function(res) {
       function loop(i) {
         if(i < res.data.results.length) {
           return saveToParse(res.data.results[i]).then(function() {
             return delay(100);
           }).then(function() {
             return loop(i + 1);
           });
         }
         else return Promise.resolve(res);
       };
       return loop(0);
     }).then(function(res) {
       console.log("finished saving");
     });



function delay(time) {
  return new Promise(function(resolve, reject) {
    setTimeout(resolve, time);
  });
}

function saveToParse(exercise) {
  return new Promise(function(resolve, reject) {
    console.log(exercise);
    ParseFactory.provider('Exercises/').edit(exercise.objectId, exercise)
      .success(resolve).error(function(response) {
        var error = {
          "message": "Please check your connection",
          "errorObject": response
        };
        reject(error);
        $ionicLoading.hide();
        $rootScope.$emit('errorEvent', error);
      });
  });
}

修改 但是这样做可能会更好。它的优势在于可以保留承诺,以便继续保持承诺。

$http.get('data/full_data.json')
     .then(function(res) {
       var p = Promise.resolve();
       res.data.results.forEach(function(elem) {
         p = p.then(function() {
           return saveToParse(elem).then(function() {
             return delay(100);
           });
         });
       });
       return p;
     });

<强> EDIT2: 另一种推广异步循环的解决方案。

function asyncWhile(cond, body) {
  if(cond()) {
    return body().then(function() {
      return asyncWhile(cond, body);
    });
  } else {
    return Promise.resolve();
  }
}

function asyncFor(start, end, body) {
  var i = start;
  return asyncWhile(function() {return i < end}, function() {
    return body(i++);
  });
}

$http.get('data/full_data.json')
     .then(function(res) {
       return asyncFor(0, res.data.results.length, function(i) {
         return saveToParse(res.data.results[i]).then(function() {
           return delay(100);
         });
       }).then(function() {
         return res;
       });
     }).then(function(res) {
       console.log("finished saving");
     });