错误之后继续承诺

时间:2018-02-06 20:50:38

标签: javascript asynchronous vue.js promise async-await

我有一些异步代码需要在出现错误时停止但仍在执行:

async saveCoupons({ state, rootState, dispatch, commit }) {
    const promises = []
    state.userCoupons.forEach(coupon => { 
        if (coupon.isNew && coupon.isUpdated) {
            // if the user is creating a new coupon
            promises.push(Vue.axios.post('/api_producer/coupons.json', coupon, { params: { token: coupon.token } }))
        } else if (!coupon.isNew && coupon.isUpdated) {
            // if the user is updating the coupon
            promises.push(Vue.axios.patch(`api_producer/coupons/${coupon.id}/`, coupon, { params: { token: coupon.token } }))
        }
    })
    try {
        await Promise.all(promises)
        dispatch('utilities/showModal', 'success', { root: true })
        dispatch('fetchProducerCoupons')
    } catch (err) {
        let couponToken = err.request.responseURL.split('token=')[1]
        commit('ADD_ERROR_ON_COUPON', couponToken)
        console.log(err)
    }
}

这是代码当前的结构,它的工作原理,但我意识到这很糟糕。我需要做的是停止执行

dispatch('utilities/showModal', 'success', { root: true })
dispatch('fetchProducerCoupons')

如果其中一个api调用失败。我想在forEach中捕获错误,所以我已经有了可用的项目,我可以立即添加错误,而不是在之后执行(这是我现在正在使用{ params: { token: coupon.token } }

3 个答案:

答案 0 :(得分:2)

我认为最好的方法是将Vue.axios请求包装到您自己的Promise中。然后,如果请求失败,您的错误中会有优惠券令牌。

这样的东西



const promises = [];

promises.push(
  Vue.axios.post('/api_producer/coupons.json', coupon)
    .catch(() => { throw new Error(coupon.token) }));
    
Promise.all(promises).catch(tokens => {
  tokens.forEach(token => {
    // Commit/handle errorous token
  });
});




答案 1 :(得分:0)

您可以将api调用包装在另一个承诺中并检查状态。像这样:

promises.push(

  new Promise((resolve, reject) => {

    Vue.axios.post('/api_producer/coupons.json', coupon, { params: { token: coupon.token } })
    .then((response) => {
      if (response.status !== 200) {
        coupon.error = true;
        reject();
      } else {
        resolve();
      }
    });

  })
);

reject将阻止执行这两行:

  dispatch('utilities/showModal', 'success', { root: true })
  dispatch('fetchProducerCoupons')  

答案 2 :(得分:0)

感谢Moritz Schmitzv.Hülst& sklingler93的帮助,我重新组织了代码,它正在工作。

我想知道是否有办法只使用async / await编写所有这些...如果有人有想法,我很乐意看到它:)

saveCoupons({ state, rootState, dispatch, commit }) {
    const promises = []
    state.userCoupons.forEach(coupon => {          
        if (coupon.isNew && coupon.isUpdated) {
            // if the user is creating a new coupon
            promises.push(new Promise((resolve, reject) => {
                Vue.axios.post('/api_producer/coupons.json', coupon)
                    .then(response => resolve(response))
                    .catch(err => {
                        reject(err)
                        commit('ADD_ERROR_ON_COUPON', coupon.token)
                    })                        
            }))
        } else if (!coupon.isNew && coupon.isUpdated) {
            // if the user is updating the coupon
            promises.push(new Promise((resolve, reject) => {
                Vue.axios.patch(`api_producer/coupons/${coupon.id}/`, coupon)
                    .then(response => resolve(response))
                    .catch(err => {
                        reject(err)
                        commit('ADD_ERROR_ON_COUPON', coupon.token)
                    })
            }))
        }
    })
    Promise.all(promises)
        .then(() => {
            dispatch('utilities/showModal', 'success', { root: true })
            dispatch('fetchProducerCoupons')
        })
        .catch(err => console.error(err))
},