Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/392.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_Async Await - Fatal编程技术网

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

Javascript 使用多个异步/等待调用构建对象,javascript,async-await,Javascript,Async Await,我使用的api在两个端点上都有数据: /新闻给了我一个包含少量属性的文章列表 /news/{id}/metadata获取文章的所有属性 我实际上需要获得所有属性,并且我计划构建一个主对象来驱动我的UI 目前的职能: getNews:一个异步/等待函数,它成功地从/news获取文章列表 getMetaPerArticle:另一个接受ID并调用/news/{ID}/metadata的异步/await函数 行为: 我运行getNews异步函数并等待响应 当响应通过时,我映射响应数组,并对数组

我使用的api在两个端点上都有数据:

  • /新闻给了我一个包含少量属性的文章列表
  • /news/{id}/metadata获取文章的所有属性
我实际上需要获得所有属性,并且我计划构建一个主对象来驱动我的UI

目前的职能:

  • getNews:一个异步/等待函数,它成功地从/news获取文章列表
  • getMetaPerArticle:另一个接受ID并调用/news/{ID}/metadata的异步/await函数
行为:

  • 我运行getNews异步函数并等待响应
  • 当响应通过时,我映射响应数组,并对数组中的每个项运行getMetadata函数
  • 一旦getMetadata完成,结果将存储为常量,并分配给element.metadata
问题: -我的两个函数都解析,但我的最终对象包含Promise.resolve对象。对象具有正确的值

代码

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));
    }
  };
输出

(6) [{…}, {…}, {…}, {…}, {…}, {…}]
0: {
    abstract: "",
    ...
    metadata: Promise {<resolved>: {...}}
}
(6)[{…},{…},{…},{…},{…},{…},{…}]
0: {
摘要:“,
...
元数据:承诺{:{…}
}

getMetaPerArticle返回一个承诺,因此在尝试映射到parsedEnDataWithMeta之前,您需要等待这些承诺得到解决。大概是这样的:

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

getMetaPerArticle返回一个承诺,因此在尝试映射到parsedEnDataWithMeta之前,您需要等待这些承诺得到解决。大概是这样的:

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

您的问题是
getMetaPerArticle
返回一个承诺,因此需要添加一个
wait
,并将箭头函数标记为
async

const parsedEnDataWithMeta = parsedEnData.map(async article => {
  const mergedArticleWithMeta = {
    ...article,
    ...await getMetaPerArticle(article.id)
  };
  return mergedArticleWithMeta;
});
之后,
parsedEnDataWithMeta
将保存一个承诺列表,因此您需要等待,直到使用
Promise解决所有承诺。所有

const parsedEnDataWithMeta = await Promise.all(parsedEnData.map(async article => {
  const mergedArticleWithMeta = {
    ...article,
    ...await getMetaPerArticle(article.id)
  };
  return mergedArticleWithMeta;
}));
如果您需要更频繁地使用它,那么您可以定义一个映射函数来处理承诺:

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

您的问题是
getMetaPerArticle
返回一个承诺,因此需要添加一个
wait
,并将箭头函数标记为
async

const parsedEnDataWithMeta = parsedEnData.map(async article => {
  const mergedArticleWithMeta = {
    ...article,
    ...await getMetaPerArticle(article.id)
  };
  return mergedArticleWithMeta;
});
之后,
parsedEnDataWithMeta
将保存一个承诺列表,因此您需要等待,直到使用
Promise解决所有承诺。所有

const parsedEnDataWithMeta = await Promise.all(parsedEnData.map(async article => {
  const mergedArticleWithMeta = {
    ...article,
    ...await getMetaPerArticle(article.id)
  };
  return mergedArticleWithMeta;
}));
如果您需要更频繁地使用它,那么您可以定义一个映射函数来处理承诺:

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

谢谢你的帮助!我在getMetaPerArticle中尝试了Promise.resolve,但仍然返回了一个承诺,我想这是因为async/Wait包装器。承诺。getNews中的所有()都起到了很好的作用。是的,异步函数总是返回一个承诺。和
Promise.resolve
是创建立即进入“已解决”状态的承诺的快捷方式。感谢您的帮助!我在getMetaPerArticle中尝试了Promise.resolve,但仍然返回了一个承诺,我想这是因为async/Wait包装器。承诺。getNews中的所有()都起到了很好的作用。是的,异步函数总是返回一个承诺。和
Promise.resolve
是创建立即进入“已解决”状态的承诺的快捷方式。