Javascript 超时循环将多行保存到 Parse.com
Javascript timeout loop to save multiple rows to Parse.com
我用 parse.com 云代码编写了一个 beforeSave
脚本。我想保存我所有的结果进行解析,所以它们都是 运行 通过这个脚本并且它们的数据在保存之前被修改。
我已经通过以下方式解决了这个问题。
已从 Parse.com 仪表板导出 JSON。
在我的应用程序中将其用作本地 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");
});
我用 parse.com 云代码编写了一个 beforeSave
脚本。我想保存我所有的结果进行解析,所以它们都是 运行 通过这个脚本并且它们的数据在保存之前被修改。
我已经通过以下方式解决了这个问题。
已从 Parse.com 仪表板导出 JSON。
在我的应用程序中将其用作本地 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");
});