使用带有promise的forEach(),而访问前一个promise会导致.then()链?

wiz*_*ard 7 javascript scope promise ecmascript-6 es6-promise

我有承诺的以下功能:

const ajaxRequest = (url) => {
  return new Promise(function(resolve, reject) {
    axios.get(url)
      .then((response) => {
        //console.log(response);
        resolve(response);
      })
      .catch((error) => {
        //console.log(error);
        reject();
      });
  });
}


const xmlParser = (xml) => {
  let { data } = xml;
  return new Promise(function(resolve, reject) {
    let parser = new DOMParser();
    let xmlDoc = parser.parseFromString(data,"text/xml");

    if (xmlDoc.getElementsByTagName("AdTitle").length > 0) {
      let string = xmlDoc.getElementsByTagName("AdTitle")[0].childNodes[0].nodeValue;
      resolve(string);
    } else {
      reject();
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试为JSON数组中的每个对象应用这些函数:

const array = [{"id": 1, "url": "www.link1.com"}, {"id": 1, "url": "www.link2.com"}]
Run Code Online (Sandbox Code Playgroud)

我提出了以下解决方案:

function example() {
    _.forEach(array, function(value) {
        ajaxRequest(value.url)
            .then(response => {
                xmlParser(response)
            .catch(err => {
                console.log(err);
            });
        });
    }
 }
Run Code Online (Sandbox Code Playgroud)

我想知道这个解决方案是否可以接受两件事:

  1. 在以下事项中对承诺申请Each()是一种好的做法.

  2. 有没有更好的方法将先前的promise结果作为then()链中的参数传递?(我正在通过responseparam).

gue*_*314 5

您可以使用.reduce()访问以前的Promise.

function example() {
    return array.reduce((promise, value) =>
       // `prev` is either initial `Promise` value or previous `Promise` value
       promise.then(prev => 
         ajaxRequest(value.url).then(response => xmlParser(response))
       )
    , Promise.resolve())
 }
 // though note, no value is passed to `reject()` at `Promise` constructor calls
 example().catch(err => console.log(err)); 
Run Code Online (Sandbox Code Playgroud)

请注意,Promise构造ajaxRequest函数在函数中不是必需的。

const ajaxRequest = (url) => 
    axios.get(url)
      .then((response) => {
        //console.log(response);
        return response;
      })
      .catch((error) => {
        //console.log(error);
      });
Run Code Online (Sandbox Code Playgroud)