异步标注的替代方案?

jun*_*var 2 javascript asynchronous repository-pattern promise angularjs

假设我们有一个简单的前端和(如果需要的话,假设Angular)和一个后端应用程序。假设前端应用发出了get请求。通常,角度存储库发出一个$http.get请求,该请求返回一个承诺(角度1)或一个可观察到的可转换为承诺的对象(角度2或4),然后该存储库返回该承诺。然后,角度服务看起来像

repository.makeTheGetCall().then(function (response) {
  // process response
}); 
Run Code Online (Sandbox Code Playgroud)

通常没关系。

1)但是,如果服务上的所有逻辑都依赖于此1调用怎么办?然后,我们实质上将整个服务嵌套在.then子句中。

2)或者,如果根据第一个Get请求的响应,我们又发出另一个请求。然后根据该响应,发出另一个请求,依此类推。然后,我们将束缚一堆then子句。

两种情况似乎都不罕见,并且两种情况都导致看起来“丑陋”的代码。是否可以使用其他实践来允许异步调用,而不必从存储库层向服务层返回promise?

谢谢 :)

van*_*rov 6

您可以使用async/await。这是传统.then()承诺处理的唯一替代方法。

因此,不要这样做:

someServiceMethod() {
  repository.makeTheGetCall().then(function (response) {
    // process response
  }); 
}
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

async someServiceMethod() {
  const response = await repository.makeTheGetCall()
  // process response
}
Run Code Online (Sandbox Code Playgroud)

最酷的事情是我们没有“ callback hell”的任何起点,代码现在固定了(在列表中排名第一)

另外,如果其中一个Promises被拒绝,我们可以在try/catch块中处理错误。这样做的好处是我们可以拥有一个捕获所有错误的地方。(您列表中的#2):

async someServiceMethod() {
  try {  
    const response = await repository.makeTheGetCall()
    const data = await repository.getDataForResponse(response)
    // process data or make another async call
  } catch (err) {
    // process error
  }
}
Run Code Online (Sandbox Code Playgroud)

关于如何使用它的很好的解释

  • “ *在try / catch块中包装包含await的代码行也是一种很好的做法*”-不。就像在每个返回诺言的函数调用上放置`.catch()`并不是一个好习惯。当您想要*处理错误时,只应使用`catch`(两者之一),否则就让它冒泡给您的呼叫者。 (2认同)