Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.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 使用Promise.all调用多个API并分派一个操作_Javascript_Reactjs_Asynchronous_Redux_Es6 Promise - Fatal编程技术网

Javascript 使用Promise.all调用多个API并分派一个操作

Javascript 使用Promise.all调用多个API并分派一个操作,javascript,reactjs,asynchronous,redux,es6-promise,Javascript,Reactjs,Asynchronous,Redux,Es6 Promise,我想调用多个API并将每个响应数据存储在一个对象中,然后我想分派这个响应对象,但我没有定义 下面是我试过的代码。我能知道我哪里做错了吗 /* COMPONENT.JSX */ componentDidMount() { callApis(this.props.products, this.props.profileId); } /* API.JS */ const getContactDetails = (http, profileId) => (http.get(`https:

我想调用多个API并将每个响应数据存储在一个对象中,然后我想分派这个响应对象,但我没有定义

下面是我试过的代码。我能知道我哪里做错了吗

/* COMPONENT.JSX */
componentDidMount() {
  callApis(this.props.products, this.props.profileId);
}

/* API.JS */
const getContactDetails = (http, profileId) => 
 (http.get(`https://www.fakeurl.com/${profileId}/contact`));

const getProductDetails = (http, profileId) => 
  (http.get(`https://www.fakeurl.com/${profileId}/product`));

const callApis = (products, profileId) => (dispatch) => {

  const payload = new Map();

  products.forEach((product) => {

  const apis = [getContactDetails, getProductDetails];

  apis.map(api => api(http, profileId));

  Promise.all(apis)
      .then((response) => {
          const apiData = {
              contactData: getParsedContactData(response[0]),
              productData: getParsedProductData(response[1])
          };
          if (payload.get(product.token)) {
              payload.get(companion.token).push(apiData);
          } else {
              payload.set(product.token, [apiData]);
          }
      })
      .catch(err => {
          throw ('An error occurred ', err);
      });
   });
   dispatch({ type: FETCH_API_DATA, payload: payload });
}

我希望在解析所有API并将其映射到负载对象后,将调用分派。然后,它将分派。

Array.map返回一个新数组,您将丢弃该数组

您在任何异步代码运行之前调用dispatch

需要做一些小改动

/* API.JS */
const getContactDetails = (http, profileId) => http.get(`https://www.fakeurl.com/${profileId}/contact`);

const getProductDetails = (http, profileId) => http.get(`https://www.fakeurl.com/${profileId}/product`);

const callApis = (products, profileId) => (dispatch) => {
    const payload = new Map();
    // *** 1
    const outerPromises = products.map((product) => {

        const apis = [getContactDetails, getProductDetails];
        // *** 2
        const promises = apis.map(api => api(http, profileId));

        // *** 3
        return Promise.all(promises)
        .then((response) => {
            const apiData = {
                contactData: getParsedContactData(response[0]),
                productData: getParsedProductData(response[1])
            };
            if (payload.get(product.token)) {
                payload.get(companion.token).push(apiData);
            } else {
                payload.set(product.token, [apiData]);
            }
        })
        .catch(err => {
            throw ('An error occurred ', err);
        });
    }));
    // *** 4
    Promise.all(outerPromises)
    .then(() => dispatch({
            type: FETCH_API_DATA,
            payload: payload
        })
    )
    .catch(err => console.log(err));
}
  • 使用products.map而不是products.forEach
  • 在api.map中捕获承诺,以便在
    Promise.all中使用
  • 返回承诺。所有的
    都可以等待外部承诺
  • 承诺。所有外在的承诺,等待一切完成

  • api.map(api=>api(http,profileId))您正在丢弃结果。。。映射返回一个新数组<代码>Promise.all(api.map(api=>api(http,profileId)))。然后
    会做你想做的事你也会调用
    调度(…)之前的
    有效负载将包含任何内容-因为您正在处理的代码具有异步性质1)是的!map返回一个数组,我可以看到API的响应。2) 那么我需要在哪里调用调度?您需要在所有承诺都已解决后调用调度您的意思是我需要在
    然后
    块中调度?此解决方案不起作用。在解决步骤3之前,步骤4正在执行。奇怪的是,
    outerPromises
    不是一个挂起承诺的数组吗?事实上呼叫调度还是太早了?或者可能有错误?我在最后的承诺中添加了一个.catch。allI没有使用async或await。
    const callApis = (products, profileId) => async (dispatch) => { // use async function
      const payload = new Map();
      for (const product of products) {
        const apis = [getContactDetails, getProductDetails];
    
        apis.map(api => api(http, profileId));
    
        await Promise.all(apis)  // await all promise done
          .then((response) => {
            const apiData = {
              contactData: getParsedContactData(response[0]),
              productData: getParsedProductData(response[1])
            };
            if (payload.get(product.token)) {
              payload.get(companion.token).push(apiData);
            } else {
              payload.set(product.token, [apiData]);
            }
          })
          .catch(err => {
            throw ('An error occurred ', err);
          });
      }
      dispatch({ type: FETCH_API_DATA, payload: payload }); // dispatch will be executed when all promise done
    }