简体   繁体   English

使用多个异步/等待调用构建对象

[英]Building an object with multiple async/await calls

I'm using an api that has data on two endpoints: 我正在使用一个在两个端点上都有数据的api:

  • /news gets me the list of articles which includes a small amount of properties / news可以获取包含少量属性的文章列表
  • /news/{id}/metadata gets all of the properties of an article / news / {id} / metadata获取文章的所有属性

I actually need to get all of the properties and I'm planning to build a master object to drive my UI. 实际上,我需要获取所有属性,并且计划构建一个主对象来驱动UI。

Current functions: 当前功能:

  • getNews: an async/await function that successfully gets article list from /news getNews:一个异步/等待功能,可从/ news成功获取文章列表
  • getMetaPerArticle: another async/await function that takes an ID and call /news/{id}/metadata getMetaPerArticle:另一个异步/等待函数,它带有一个ID并调用/ news / {id} / metadata

Behaviour: 行为:

  • I run the getNews async functions and wait for the response 我运行getNews异步函数并等待响应
  • when the response comes through I map over the response array and run the getMetadata function on each of the items in the array 当响应通过时,我在响应数组上映射并在数组中的每个项目上运行getMetadata函数
  • once getMetadata is complete, result is stored to a constant, and assigned to the element.metadata 一旦getMetadata完成,结果将存储到常量中并分配给element.metadata

Problem : - both my functions resolve, but my final object contains Promise.resolve objects. 问题 :-我的两个函数都可以解析,但是我的最终对象包含Promise.resolve对象。 The objects have the correct values. 对象具有正确的值。

Code

const getNews = async options => {
    try {
      const { data } = await axios(options);
      const parsedEnDataWithMeta = parsedEnData.map(article => {
        const mergedArticleWithMeta = {
          ...article,
          ...getMetaPerArticle(article.id)
        };
        return mergedArticleWithMeta;
      });
    } catch (getNewsError) {
      dispatch(receiveNewsError(getNewsError));
    }
  };



const getMetaPerArticle = async articleID => {
    const axiosOptions = {
      method: "GET",
      url: `url`,
    };
    try {
      const response = await axios(axiosOptions);
      return response.data;
    } catch (err) {
      console.error(err);
      dispatch(receiveNewsError(err));
    }
  };

Output 输出量

(6) [{…}, {…}, {…}, {…}, {…}, {…}]
0: {
    abstract: "",
    ...
    metadata: Promise {<resolved>: {...}}
}

getMetaPerArticle returns a promise, so you'll need to wait for those promises to resolve before you try to map to parsedEnDataWithMeta. getMetaPerArticle返回了一个Promise,因此在尝试映射到parsedEnDataWithMeta之前,您需要等待这些Promise解析。 Something like this: 像这样:

const getNews = async options => {
  try {
    const { data } = await axios(options);
    const metadataPromises = data.map(article => getMetaPerArticle(article.id));
    const metadata = await Promise.all(metadataPromises);
    const parsedEnDataWithMeta = data.map((article, i) => ({
      ...article,
      ...metadata[i]
    });
  } catch (getNewsError) {
    dispatch(receiveNewsError(getNewsError));
  }
};

Your Problem is that getMetaPerArticle returns a Promise so you need to add an await in fornt of it, and mark the arrow function as async . 您的问题是getMetaPerArticle返回一个Promise,因此您需要在其中添加一个await ,并将箭头函数标记为async

const parsedEnDataWithMeta = parsedEnData.map(async article => {
  const mergedArticleWithMeta = {
    ...article,
    ...await getMetaPerArticle(article.id)
  };
  return mergedArticleWithMeta;
});

After that parsedEnDataWithMeta will hold a list of Promises, so you would need to wait untill all of them are resolved using Promise.all : 之后, parsedEnDataWithMeta将保存一个Promises列表,因此您需要等到所有它们都使用Promise.all解析Promise.all

const parsedEnDataWithMeta = await Promise.all(parsedEnData.map(async article => {
  const mergedArticleWithMeta = {
    ...article,
    ...await getMetaPerArticle(article.id)
  };
  return mergedArticleWithMeta;
}));

If you need to use that more often then you could define you a map function that will handle promises: 如果您需要更频繁地使用它,则可以定义一个处理承诺的map函数:

function promiseMap( array, callback ) {
  return Promise.all(array.map(callback))
}


const parsedEnDataWithMeta = await promiseMap(parsedEnData, async article => {
  const mergedArticleWithMeta = {
    ...article,
    ...await getMetaPerArticle(article.id)
  };
  return mergedArticleWithMeta;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM