使用promise在for循环中请求与订单相关的信息
Using promises to request order-dependent information in a for loop
我有一个相对简单的任务;现有的信息已经过期,所以我必须从API请求信息,修改现有的信息文件并将其推回到服务器,更新。该信息采用json文件的形式;很简单。该文件包含一个对象,该对象具有一组必须更新的属性的对象。这就是问题发生的地方;对象数组生成一个API请求数组,其响应必须与生成请求的原始对象匹配(因为响应包含必须在对象中更新的信息)。
这就是我迄今为止所做的承诺的要点:
function main() {
// First get existing data.
getExistingData().then(function(result) {
console.log(result); // It worked, return it for next 'then' to use.
return result;
}, function(err) {
console.log(err); // This usually never happens.
}).then(function(result) { // Use the existing data to generate the requests for new data.
requestNewData(result).then(function(moddedJson) {
console.log(moddedJson); // This happens BEFORE I get responses back from the request, which is wrong.
});
});
}
function getExistingData() {
return new Promise(function(resolve, reject) {
fetch('dataURLHere')
.then(function(res) {
resolve( res.json()); // Turn result into JSON, and return it.
})
})
}
function requestNewData(rawJson) {
return new Promise(function(resolve) {
// Loop over the number of objects in the original data.
for (var i = 0; i < rawJson.length; i++) {
// Loop over the array of objects within each object.
for (var multiId = 0; multiId < rawJson.hits.length; multiId++) {
var requestUrl = "someURLConstructedFromJsonData";
var hit = rawJson.hits[multiId];
new Promise(function(resolve) {
request(requestUrl, function(error, response, body) {
if (!error && response.statusCode == 200) {
// Need to parse the XML response into a js object.
parseString(body, function (err, result) {
hit.propertyToChange = result.propertyToChange;
hit.propertyToChange2 = result.propertyToChange2;
});
}
else {
console.log("No data for this item.");
}
resolve(hit);
});
})
}
}
resolve(rawJson);
})
}
基本上,我想发生的事情是:1) 获取原始数据。这很容易,并且已经通过我的代码完成了。2) 使用原始数据为数据中的每个文档以及每个文档中的每组属性生成请求。这也不是问题。3) 确保从请求返回的数据与现有数据匹配。这是我无法理解的问题部分。
问题是解决得太早。
危险信号是当你创造了一个承诺,但从不做任何事情:
new Promise(function(resolve) {
request(requestUrl, function(error, response, body) {
...
这个承诺确实得到了正确的解决,但没有人在等待它。简单的解决方案是promise.all:
function requestNewData(rawJson) {
return new Promise(function(resolve, reject) {
var promises = [];
for (var i = 0; i < rawJson.length; i++) {
...
promises.push(new Promise(function(resolve) {
...
}));
}
resolve(Promise.all(promises));
});
}
现在,Promise.all(promises)
将通过一组结果进行解析。这可能并不理想,但如果你只想等待使用它,你可以,但前提是:
return Promise.all(promises).then(function() {
resolve(updatedJson);
}, reject);
通过这种方式,您可以让每个单独的承诺修改响应数据。requestNewData
返回的promise在完成所有这些操作之前不会解析,因此此时updatedJson
将被更新。
请注意:Promise.all具有快速失败行为。就你而言,我认为这正是你想要的。但是,如果你需要知道哪些失败了,或者如果你需要等到所有请求完成(失败或其他),Promise.all可能不是正确的选择。
PS:如果request()
函数提供了error
,那么您可能应该使用reject
。否则,如果出现网络错误,你的数据可能会出现漏洞,而不会被拒绝。
- JS表单提交"无法使用Chrome数据保护程序加载此页面.尝试重新加载页面.调试信息:POST CISmtuK
- 包含数据库中相关信息的开放模态
- 根据选择选项元素将表单重定向到不同的URL,并在电子邮件中获取表单详细信息
- 通过javascript提示获取表单的信息
- 如何获取给定表单详细信息的嵌套json对象
- 使用GM-xmlhttpRequest而不是iframe来显示来自外部页面的相关信息
- 图像 onclick() 函数显示带有表单详细信息的 dailog 窗口
- jquery:如何将表单元素信息传递给另一个函数
- jQuery jVector Map onRegionClick显示相关信息
- 谷歌地图API方向上的时间相关信息
- php表单详细信息到手机号码
- 启用js文件时,联系人表单不会发送所有表单详细信息
- 重定向到任何页面并提交表单详细信息
- 在Dynamics CRM 2011表单中显示相关信息
- 如何设置登录表单提醒信息,“虚假登录表单”
- 使用电子表格向HTML表单提供信息
- 使用 JQuery 从 GET 响应中获取相关信息
- 无法使用 html 表单和信息框显示默认文本.js
- 如何在asp.net中使用javascript显示与所单击项目相关的信息
- 将JSON附加到具有相关信息的HTML容器中