同时解决多个承诺后如何返回数据?

时间:2018-10-18 08:28:17

标签: node.js asynchronous async-await

我在这里创建了一个数据对象

const data = new Object();

然后我要同时调用多个API

datamuse.request(`words?ml=${text}`)
    .then((list) => {
      data.ml = list;
    })
    .catch((error) => {
      console.log(error);
    });

  datamuse.request(`words?sp=${text}`)
    .then((list) => {
      data.sp = list;
    })
    .catch((error) => {
      console.log(error);
    });

  datamuse.request(`words?rel_trg=${text}`)
    .then((list) => {
      data.rel = list;
    })
    .catch((error) => {
      console.log(error);
    });

  datamuse.request(`sug?s=${text}`)
    .then((list) => {
      data.sug = list;
    })
    .catch((error) => {
      console.log(error);
    });

  datamuse.request(`words?sl=${text}`)
    .then((list) => {
      data.sl = list;
    })
    .catch((error) => {
      console.log(error);
    });

最后返回数据:

return data;

数据将返回为undefined。 我知道我正在同时执行异步操作。

但是我不想在这种情况下使用函数生成器,因为它太慢了。

有人可以帮助我从数据中获取这些值,然后将其返回吗?

2 个答案:

答案 0 :(得分:1)

类似

Promise.all([
  datamuse.request(`words?ml=${text}`),
  datamuse.request(`words?sp=${text}`),
  datamuse.request(`words?rel_trg=${text}`),
  datamuse.request(`sug?s=${text}`),
  datamuse.request(`words?sl=${text}`),
]).then(([
  ml,
  sp,
  rel,
  s,
  sl
]) => {
  const data = {
    ml,
    sp,
    rel,
    s,
    sl,
  };
}).catch((err) => {
  // Deal with error
});

甚至更好的是您必须添加一些字词和字词差异,让您知道:)

const elems = [
  'ml',
  'sp',
  'rel_trg',
  's',
  'sl',
];

Promise.all(elems.map(x => datamuse.request(`words?${x}=${text}`))
    .then((rets) => {
      const data = elems.reduce((tmp, x, xi) => ({
         ...tmp,

         [x]: rets[xi];
      }), {});
    }).catch((err) => {
      // Deal with error
    });




好的,这是解决您的wordssug问题的一种可能的解决方法

const elems = [{
  acronym: 'ml',
  req: 'words',
}, {
  acronym: 'sp',
  req: 'words',
}, {
  acronym: 'rel_trg',
  req: 'words',
}, {
  acronym: 's',
  req: 'sug',
}, {
  acronym: 'sl',
  req: 'words',
}];

Promise.all(elems.map(({
      acronym,
      req,
    }) => datamuse.request(`${req}?${acronym}=${text}`))
    .then((rets) => {
      const data = elems.reduce((tmp, {
        acronym,
      }, xi) => ({
        ...tmp,

        [acronym]: rets[xi];
      }), {});
    }).catch((err) => {
      // Deal with error
    });

答案 1 :(得分:0)

Promise.resolve是前往此处的方法。 另外,我建议将逻辑与数据分开。

function getResult(where) {
  const result = {}
  return Promise.all(
    Object
      .entries(where)
      .map(([key, path]) => datamuse.request(path).then(list => result[key] = list))
  )
  .then(() => result)
}

function createMapForText(text) {
  return {
    ml: `words?ml=${text}`,
    sp: `words?sp=${text}`,
    rel: `words?rel_trg=${text}`,
    sug: `sug?s=${text}`,
    sl: `words?sl=${text}`
  }
}

// ----- Testing -----

// Fake `datamuse` for testing purposes only
const datamuse = {
  request: (path) => Promise.resolve('hello')
}

getResult(
  createMapForText('hello')
).then(console.log.bind(console))