Javascript for循环承诺
Javascript for loop Promises
我有一个像这样的url数组
var urls = ["www.google.com", "www.yahoo.com"];
我想通过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)}
}
但是现在它没有等待readResponse_async完成,我怎么能让它等待呢?
感谢编辑
阅读响应后,我保存到我的数据库,我有另一个数组像这样
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?
//**************************
}
因为有了你的回答我有
function retry() {
if (urlsUnion.length > 0) {
var nextUrl = urlsUnion.pop();
//********** ADDED LINE
var nextLoc = location.pop();
Parse.Cloud.httpRequest({
url: nextUrl,
}).then(function(httpResponse) {
xmlReader.read(httpResponse.text, function (err, res) {
if(err) {
// show an error
} else {
//********** ADDED LINE
saveLoc_async(res, nextLoc);
retry();
}
});
});
}
}
那么retry();
应该去哪里,因为现在与保存有时它把第二个位置与第一项url之一?为什么会这样?
我为一个动画做了类似的事情。
var actions = [drawXXX, fadeOutYYY, drawXYZ];
this.startAnimation = function () {
actions.reduce(function (previousAction, nextAction) {
return previousAction.then(nextAction)
}, $.when());
}
您的代码会立即触发这两个url,而不会在两者之间等待。
你要做的是从数组中删除第一个url并触发它。在'then'分支中检查数组中是否还有url,然后重复。
像这样(未经测试,编辑使代码再次干净):
var xmlReader = require('cloud/xmlreader.js');
function readResponse_async(xlmString) {
xmlReader.read(xlmString, function (err, res) {
if(err) {
// show an error
} else {
readFirstUrl();
}
});
}
function readFirstUrl() {
if (urlsUnion.length == 0) {
return;
}
var url = urlsUnion.pop();
Parse.Cloud.httpRequest({
url: url,
}).then(function(httpResponse) {
readResponse_async(httpResponse.text);
});
}
readFirstUrl();
我不确定我理解你使用的unionUrls
数组,但如果你有你的URL在urls
数组,我认为这是相当干净的:
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);
相关文章:
- 等待循环调用的所有承诺完成
- 而循环使用蓝鸟承诺
- 蓝鸟承诺循环
- javascript承诺在循环中或如何逐个调用函数
- 循环中的承诺问题
- 转换嵌套'对于'循环成一个承诺,为了一个承诺?嵌套承诺
- 在循环中解析所有承诺后返回值
- 从 foreach 循环链接承诺
- 链接在webdriver.io中的while循环中承诺
- 循环超出范围,不执行承诺链
- 在nodejs中使用Q.js承诺进行循环的正确方法
- 如何仅从循环中调用最后的承诺
- 同时循环承诺,直到另一个承诺结束
- AngularJS:app.run() 中的承诺永远陷入循环
- 承诺:循环后执行
- 使用延迟和承诺循环ajax调用
- AngularJS承诺循环错误
- 节点承诺循环等待结果
- 如何在jquery中使用承诺循环
- Selenium WebdriverJS承诺循环