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

Javascript timeout loop to save multiple rows to Parse.com

我用 parse.com 云代码编写了一个 beforeSave 脚本。我想保存我所有的结果进行解析,所以它们都是 运行 通过这个脚本并且它们的数据在保存之前被修改。

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

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

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

代码:

$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 秒内完美运行,然后运行缓慢...请参阅网络 activity.

的屏幕截图

您可以实现所有功能 return 承诺。为了使循环异步,您将其转换为递归 "loop".

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

编辑: 但是,这样做可能会更好。它具有 return 承诺的优势,因此您可以继续链接您的承诺。

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