承诺:跳过所有实现和拒绝的反应,但最终执行。

时间:2019-04-23 17:47:32

标签: javascript vue.js promise

我有一个名为request的函数:

function request (endpoint) {
  return axios.request(endpoint).then(api.onSuccess).catch(api.onError)
}

api.onSuccess

  onSuccess (response) {
    let breakChain = false
    ... some logic goes here ...
    return breakChain ? (new Promise(() => {})) : response
  }

api.onError

  onError (error) {
    let breakChain = false
    ... some logic goes here ...
    if (breakChain) {
      return new Promise(() => {})
    } else {
      throw error
    }
  }

api拥有许多函数,这些函数根据提供的端点数据表示不同的API调用并返回request(endpoint)

目前,我有代码,如您所见,它以空的执行器返回Promise,该执行器始终处于待处理状态,以阻止后续.then(...).catch(...)处理程序链的执行,因为它们无限地等待为了那个诺言解决。这样做是为了处理具有共同响应处理的某些API响应(例如代码> = 500的响应)。 问题是,现在我需要调用.finally()(就像在Vue Cookbook-https://vuejs.org/v2/cookbook/using-axios-to-consume-apis.html#Dealing-with-Errors中一样)以恢复某些组件的状态,无论是否存在错误,但是挂起Promise的方法是一种障碍。

问题是:是否可以跳过其中一个处理程序中的所有后续.then(...).catch(...)调用,直接转到.finally()

更新。我没有提到重要的一点-api.onSuccessapi.onError基本处理程序。在另一个应用程序组件中,在request函数中提供的该基本链的末尾附加了附加的处理程序。通常,某些API调用链具有以下结果形式:

return axios.request(endpoint).then(api.onSuccess).catch(api.onError).then((response) => {...}).catch(() => {...}).finally(() => {...})

(有时没有.finally().catch(...)块)

2 个答案:

答案 0 :(得分:1)

  

是否可以跳过其中一个处理程序中的所有后续.then(...).catch(...)调用以直接转到.finally()

No.

  

目前,我通过无限等待来阻止链条-但是这种等待Promise的方法是一个障碍。

确实,不要那样做。您可以通过using rejections (exceptions) for flow control跳过then处理程序,但是更合适的方法是通过嵌套要跳过的inside an if statement链的一部分来处理此问题。

  

完成此操作是为了处理具有常见响应处理的某些API响应(例如代码> = 500的响应)

为此,您应该使用类似的

return axios.request(endpoint).then(response => {
    …
}).catch(error => {
    if (api.handleCommonError(error)) return; // returns false if it couldn't handle the error
    …
}).finally(() => {
    …
});

是的,您无法在api.request函数中隐藏这种错误处理。

答案 1 :(得分:0)

您可以使用asyncawait。所有现代的浏览器都支持它们,并且您的捆绑软件可以使它们与旧的浏览器兼容。

例如:

async function request (endpoint) {
  try {
    const response = await axios.request(endpoint);
    return api.onSuccess(response);
  } catch (err) {
    api.onError(err);
  } finally {
    // Always executed, even if no error was thrown
  }
}

您也可以更传统地做到这一点:

function request (endpoint) {
  return axios.request(endpoint).then(api.onSuccess, api.onError).then(() => {
    // Code is always executed after error / success
  }
}