Redux链中的多个Ajax承诺在一个Action中

时间:2016-11-18 15:21:29

标签: redux react-redux superagent

我有一个需要进行2次后续ajax调用的Redux操作。

第一次调用googlemaps api:https://maps.googleapis.com/maps/api/geocode/json?address=${searchTerm}&key=${gmapsKey}

第二个根据这些结果调用本地服务 /api/content/stores/byDistance/${lat},${lng}/sort

我使用superagent进行ajax调用。很明显,我很难跟踪承诺,包括失败。

我是否错误地承诺了Promises的核心概念?有没有更简单的方法来写下面的内容?

export function loadBySearch(searchTerm) {

    const geoSearchUrl = `https://maps.googleapis.com/maps/api/geocode/json?address=${searchTerm}&key=${gmapsKey}`;

    return {
        types: [LOAD, LOAD_BY_LAT_LONG, LOAD_FAIL],
        //Do I need to make this promise here?
        promise: (client) => {
            const promise = new Promise( (resolve, reject) => {
                console.info('making google geocode request', geoSearchUrl);
                superagent.get(geoSearchUrl)
                    .set('Accept', 'application/json')
                    .then( (successData1) =>{
                        const results = successData1.body.results;
                        if (!results.length) {
                            reject(`no results found for this search : ${searchTerm}`);
                            return;
                        }
                        const lat = results[0].geometry.location.lat;
                        const lng = results[0].geometry.location.lng;
                        const path = `/api/content/stores/byDistance/${lat},${lng}/sort`;
                        client.get(path).then(
                            (successData2) => {
                                resolve( {
                                    searchTerm: searchTerm,
                                    searchLocation: {
                                        lat,
                                        lng
                                    },
                                    data: successData2
                                });
                            },
                            (errorData2) => {
                                reject( {
                                    searchTerm: searchTerm,
                                    result: errorData2
                                });
                            },
                        );
                    },
                        (errorData1) => {
                            reject({
                                searchTerm: searchTerm,
                                result: errorData1
                            });
                        }
                );

            });

            return promise;
        }
    };
}

1 个答案:

答案 0 :(得分:0)

我不是在使用superagent,但我猜这样的事情可能会起作用:

superagent.get(geoSearchUrl)
  .set('Accept', 'application/json')
  .then(successData1 => {
    const results = successData1.body.results;
    if (!results.length) {
      throw(`no results found for this search : ${searchTerm}`);
    }
    return Promise.resolve(results);
  })
  .then(results => {
    const lat = results[0].geometry.location.lat;
    const lng = results[0].geometry.location.lng;
    const path = `/api/content/stores/byDistance/${lat},${lng}/sort`;
    return client.get(path);
  })
  .then(successData2 => {
    return Promise.resolve({
      searchTerm: searchTerm,
      searchLocation: {
        lat,
        lng
      },
      data: successData2
    });
  })
  .catch(error => {
    return Promise.reject({
      searchTerm: searchTerm,
      result: error
    });
  });

没有测试它,但我希望至少它有所帮助;)