循环承诺的Javascript
我有一个像这样的URL数组循环承诺的Javascript,javascript,promise,Javascript,Promise,我有一个像这样的URL数组 var urls = ["www.google.com", "www.yahoo.com"]; var location = ['USA', 'England']; function saveLoc_async(data, location) { var i3, i4, i5, m, TestItem = Parse.Object.extend("TestItem"),//can be reused within the loops?
var urls = ["www.google.com", "www.yahoo.com"];
var location = ['USA', 'England'];
function saveLoc_async(data, location) {
var i3, i4, i5, m,
TestItem = Parse.Object.extend("TestItem"),//can be reused within the loops?
promise = Parse.Promise.as();//resolved promise to start a long .then() chain
for (i3 = 0; i3 < data.count(); i3++) {
(function(testItem) {
testItem.set("item", data.at(i));
testItem.set("location", location);
//build the .then() chain
promise = promise.then(function() {
return testItem.save();
});
})(new TestItem());
//************************
//CALL retry(); here?
//**************************
}
我想在URL之间循环,并在循环中执行异步任务,直到异步任务完成后才转到下一项。我知道你可以通过承诺做到这一点,但我在这方面遇到了一些麻烦。这是我的
var xmlReader = require('cloud/xmlreader.js');
function readResponse_async(xlmString) {
var promise = new Parse.Promise();
xmlReader.read(xlmString, function (err, res) {
if(err) {
promise.reject(err);
} else {
promise.resolve(res);
}
});
return promise;
}
for (i = 0; i < urls.length; i++) {
Parse.Cloud.httpRequest({
url: unionUrls[i],
}).then(function(httpResponse) {
try {
// console.log(httpResponse.text)
return readResponse_async(httpResponse.text)
} catch (e) {console.log(e)}
}
我就这样做了
var urls = ["www.google.com", "www.yahoo.com"];
var location = ['USA', 'England'];
function saveLoc_async(data, location) {
var i3, i4, i5, m,
TestItem = Parse.Object.extend("TestItem"),//can be reused within the loops?
promise = Parse.Promise.as();//resolved promise to start a long .then() chain
for (i3 = 0; i3 < data.count(); i3++) {
(function(testItem) {
testItem.set("item", data.at(i));
testItem.set("location", location);
//build the .then() chain
promise = promise.then(function() {
return testItem.save();
});
})(new TestItem());
//************************
//CALL retry(); here?
//**************************
}
那么应该在哪里
retry()
go,因为现在使用save有时会将第二个位置与第一个项目url之一放在一起?为什么会发生这种情况?您的代码会立即触发两个URL,而不会在两者之间等待
您需要做的是从数组中删除第一个url并启动它。在“then”分支中,检查数组中是否仍有url,然后重复
如下所示(未经测试,已编辑以使代码再次干净):
我为一部动画做了类似的事情
var actions = [drawXXX, fadeOutYYY, drawXYZ];
this.startAnimation = function () {
actions.reduce(function (previousAction, nextAction) {
return previousAction.then(nextAction)
}, $.when());
}
不确定我是否理解您使用的
unionURL
数组,但如果您的URL位于URL
数组中,我认为这是非常干净的:
function getUrl(url) {
return Parse.Cloud.httpRequest(url)
.then( function(httpResponse) {
return readResponse_async(httpResponse.text);
});
}
urls.reduce( function(prev, url) {
return prev ? prev.then( function() { getUrl(url); }) : getUrl(url);
}, null);
只是为了让我明白。。。您想使用异步调用作为同步调用工作吗?异步的主要原因是允许在完成调用过程之前继续!您是否希望每个URL都单独执行,并在开始下一次迭代之前等待另一个URL的整个循环体完成?现在,如前所述,这将立即为每个URL创建一个承诺,并且每个URL都将尽可能地完成执行。即使您不能使用jQuery,也可以查看此链接中的答案,了解如何构造代码:……这是假设您希望对项列表执行异步调用,在进入下一个循环之前完成异步调用。承诺都是关于异步的——这是99%的人想要确保速度的——所以它们与你需要的正好相反think@RodrigoGomes是的,因为在我读取响应后,我保存了我的解析数据库,我想等待,这是一份背景工作,所以我不担心速度。我在答案中添加了一个例子。没有,这就是为什么我称之为未测试:)。感谢您的提示,我更新了代码以包含xml读取。。。。但是,我认为这个解决方案已经不够简单了,所以我会在我的回答中反映出来。你能在阅读url后看到关于保存的编辑吗?我现在看到了。重试最好在saveLoc_async(res,nextLoc)中完成;但现在问题变得非常复杂。