Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
每个循环中的有序JavaScript承诺_Javascript_Arrays_Node.js_Promise - Fatal编程技术网

每个循环中的有序JavaScript承诺

每个循环中的有序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

我正在创建一个XML文件,同时使用下划线在数组中循环。在这个循环中,我需要调用一个外部资源来检索一个值,以便为数组中的这个特定项编写一个XML元素

我感到困惑的是,如何在保持循环顺序的同时从外部资源检索值,以便将值包含在数组中的正确项中

我在检索值的函数中返回一个承诺,但这显然是错误的

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());
});