【问题标题】:Promise.all is finished before the promises that it's relying onPromise.all 在它所依赖的承诺之前完成
【发布时间】:2019-10-13 02:29:15
【问题描述】:

我有一个 API 请求列表,只有在所有请求都完成后我才会返回答案。我为此使用了 Promise.all ,但似乎 promise.all 的 then 是在他应该等待的承诺之前被触发的。 我认为这是因为我在发布请求中有一个获取请求。我怎样才能使这项工作?

这是一个 react-redux 项目。

if (devices) {
    const APIArray = [];
    devices.forEach(device => {
        const data = {
            id: device.id,
        };
        dispatch({ type: EDIT_DEVICE, payload: data });
        APIArray.push(
            axios
                .post('/deploy/update', data)
                .then(res => {
                    ApiUtils.get(`/deploy/device?deviceId=${data.id}`).then(response => {
                        console.log('1');
                        dispatch({ type: EDIT_DEVICE_SUCCESS, payload: { device: response.data } });
                    });
                })
                .catch(error => {
                    dispatch({ type: EDIT_DEVICE_FAIL, payload: { device: data, error: error } });
                })
        );
    });

    return Promise.all(APIArray)
        .then(res => {
            console.log('2');
            dispatch({ type: UPDATE_DEVICES_SUCCESS, payload: res });
            return res;
        })
        .catch(err => {
            return err
        );
}

expected: console.log('1')
          console.log('1')
          console.log('2')
actual: console.log('2')
        console.log('1')
        console.log('1')

【问题讨论】:

    标签: javascript promise


    【解决方案1】:

    你必须将内部的承诺返回给外部链:

     return ApiUtils.get(`/deploy/device?deviceId=${data.id}`).then(/*...*/);
    

    通过返回它,外部.then 返回的承诺将被链接。

    【讨论】:

      【解决方案2】:

      这是因为 Promise 是由 Axios.post 返回的,但是一旦你收到 post 结果,你又会进入另一个 Promise。

      APIArray.push(
              axios
                  .post('/deploy/update', data)
                  .then(res => {
                      return ApiUtils.get(`/deploy/device?deviceId=${data.id}`).then(response => {
                          console.log('1');
                          dispatch({ type: EDIT_DEVICE_SUCCESS, payload: { device: response.data } });
                      });
                  })
                  .catch(error => {
                      dispatch({ type: EDIT_DEVICE_FAIL, payload: { device: data, error: error } });
                  })
          );
      

      在then中看到,我添加了return语句。这样,ApiUtils.get 承诺就会被传递到承诺链。

      【讨论】:

        【解决方案3】:

        你应该改变

        .then(res => {
           ApiUtils.get(`/deploy/device?deviceId=${data.id}`).then(...);
        })
        

        .then(res => {
           return ApiUtils.get(`/deploy/device?deviceId=${data.id}`).then(...);
         })
        
         // or without brackets
        
        .then(res => ApiUtils.get(`/deploy/device?deviceId=${data.id}`).then(...))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-06-13
          • 2015-07-18
          • 1970-01-01
          • 1970-01-01
          • 2014-11-11
          • 2019-11-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多