每个循环中的有序JavaScript承诺
我正在创建一个XML文件,同时使用下划线在数组中循环。在这个循环中,我需要调用一个外部资源来检索一个值,以便为数组中的这个特定项编写一个XML元素 我感到困惑的是,如何在保持循环顺序的同时从外部资源检索值,以便将值包含在数组中的正确项中 我在检索值的函数中返回一个承诺,但这显然是错误的每个循环中的有序JavaScript承诺,javascript,arrays,node.js,promise,Javascript,Arrays,Node.js,Promise,我正在创建一个XML文件,同时使用下划线在数组中循环。在这个循环中,我需要调用一个外部资源来检索一个值,以便为数组中的这个特定项编写一个XML元素 我感到困惑的是,如何在保持循环顺序的同时从外部资源检索值,以便将值包含在数组中的正确项中 我在检索值的函数中返回一个承诺,但这显然是错误的 import Promise from 'bluebird'; import XMLWriter from 'xml-writer'; import _ from 'underscore'; import req
import Promise from 'bluebird';
import XMLWriter from 'xml-writer';
import _ from 'underscore';
import request from 'request';
class Tester {
writeXml() {
let stores = [
{StoreId: 1, LocationId: 110},
{StoreId: 14, LocationId: 110},
{StoreId: 15, LocationId: 110},
];
let xw = new XMLWriter();
xw.startDocument();
xw.startElement('Stores');
// Loop through all the stores to write the XML file.
_.each(stores, (s) => {
xw.startElement('Store')
.startElement('StoreId').text(s.StoreId).endElement()
.startElement('LocationId').text(s.LocationId).endElement()
// Need to call an external resource here to get the
// store code, but unsure how to do this.
this.getStoreCode(s.LocationId, s.StoreId).then((storeCode) => {
xw.startElement('StoreCode').text(storeCode).endElement();
});
xw.endElement();
});
xw.endDocument();
console.log(xw.toString());
}
getStoreCode(locationId, storeId) {
return new Promise((resolve, reject) => {
let apiUrl = 'http://127.0.0.1:3000/api/v1/stores?filter' +
'[where][locationId]=' + locationId +
'&filter[where][storeId]=' + siteId + '&filter[fields][storeCode]=true';
request(apiUrl, (error, response, body) => {
if (!error) {
let result = JSON.parse(body);
return resolve(result[0].storeCode);
} else {
return reject(error);
}
});
});
}
}
new Tester().writeXml();
未经测试,但这是一条路要走(或者更谦虚地说,是一条路要走) 及 在英语中,它使用
Promise.map()
将普通store
对象投影到具有StoreCode
属性的store对象的Promises中
然后,。其中的每一个()
都按顺序写入XML编写器
最后,整个链解析为XMLWriter对象本身,您可能希望将其更改为不同的结果
使用承诺的函数应该返回一个承诺(或调用某种回调),这样调用代码就有机会知道该函数何时完成。未经测试,但这就是方法(或者更简单地说,一种方法) 及 在英语中,它使用
Promise.map()
将普通store
对象投影到具有StoreCode
属性的store对象的Promises中
然后,。其中的每一个()
都按顺序写入XML编写器
最后,整个链解析为XMLWriter对象本身,您可能希望将其更改为不同的结果
使用承诺的函数应该返回承诺(或调用某种回调),这样调用代码就有机会知道该函数何时完成。我想,您需要先加载资源,然后编写xml结构。我同意webduvet。首先将所有资源加载到JS对象中,然后,在所有承诺都得到解决后,编写xml。看看
Promise.all
。您应该使用map
而不是forEach
我想,您需要先加载资源,然后编写xml结构我同意webduvet。首先将所有资源加载到JS对象中,然后,在所有承诺都得到解决后,编写xml。看看Promise.all
。您应该使用map
而不是forEach
是否允许省略xw.endElement()
匹配xw.startElement('Stores')
?@Roamer-1888我不确定。直觉上,我希望endDocument()
隐式结束所有打开的元素,但我没有测试(或查找)。@duffn不要忘记,如果合适的话。不定义错误行为是不理想的。@Tomalak,示例表明了这一点。顺便说一句,做得很好。是否允许省略xw.endElement()
匹配xw.startElement('Stores')
?@Roamer-1888我不确定。直觉上,我希望endDocument()
隐式结束所有打开的元素,但我没有测试(或查找)。@duffn不要忘记,如果合适的话。不定义错误行为是不理想的。@Tomalak,示例表明了这一点。顺便说一句,干得好。
writeXml(stores) {
let xw = new XMLWriter();
xw.startDocument();
xw.startElement('Stores');
return Promise.map(stores, (store) => {
return this.getStoreCode(store.LocationId, store.StoreId).then((storeCode) => {
store.StoreCode = storeCode;
return store;
});
}).each((storeWithStoreCode) => {
xw.startElement('Store');
_.each(['StoreId', 'LocationId', 'StoreCode'], (prop) => {
xw.startElement(prop).text(storeWithStoreCode[prop]).endElement();
});
xw.endElement();
}).then(() => {
xw.endDocument();
return xw;
});
}
writeXml([
{StoreId: 1, LocationId: 110},
{StoreId: 14, LocationId: 110},
{StoreId: 15, LocationId: 110},
]).then((xw) => {
console.log(xw.toString());
});