我一直在看到看起来像这样的代码:
myObj.doSome("task").then(function(env) {
// logic
});
then()
从何而来?
原文由 Kay Pale 发布,翻译遵循 CC BY-SA 4.0 许可协议
我一直在看到看起来像这样的代码:
myObj.doSome("task").then(function(env) {
// logic
});
then()
从何而来?
原文由 Kay Pale 发布,翻译遵循 CC BY-SA 4.0 许可协议
10 回答11.3k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.2k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
在 JavaScript 中处理异步调用的传统方法是使用回调。假设我们必须对服务器进行三个调用,一个接一个,以设置我们的应用程序。使用回调,代码可能类似于以下内容(假设使用 xhrGET 函数进行服务器调用):
在此示例中,我们首先获取服务器配置。然后基于此,我们获取有关当前用户的信息,然后最终获取当前用户的项目列表。每个 xhrGET 调用都采用一个回调函数,该函数在服务器响应时执行。
当然,现在我们拥有的嵌套级别越多,代码就越难阅读、调试、维护、升级和基本使用。这通常被称为回调地狱。此外,如果我们需要处理错误,我们可能需要将另一个函数传递给每个 xhrGET 调用,以告诉它在发生错误时需要做什么。如果我们只想拥有一个通用的错误处理程序,那是不可能的。
Promise API 提出以下建议:
promise
对象。promise
object will have athen
function that can take two arguments, asuccess
handler and anerror
handler.then
函数中的成功 或 错误处理程序将仅在异步任务完成后调用 _一次_。then
函数还将返回一个promise
,以允许链接多个调用。value
,它将作为argument
传递给下一个函数,在promise
b9b5dadb4f482e7080555-93a29de 链中promise
(发出另一个异步请求),则只有在该请求完成后才会调用下一个处理程序(成功或错误)。因此,前面的示例代码可能会转换为类似以下内容,使用 promises 和
$http
服务(在 AngularJs 中):传播成功和错误
链接承诺是一种非常强大的技术,它允许我们完成很多功能,比如让服务调用服务器,对数据进行一些后处理,然后将处理后的数据返回给控制器。但是当我们使用
promise
链时,我们需要记住一些事情。考虑以下假设的
promise
具有三个承诺的链,P1、P2 和 P3。每个promise
都有一个成功处理程序和一个错误处理程序,因此 P1 的 S1 和 E1,P2 的 S2 和 E2,P3 的 S3 和 E3:在没有错误的正常流程中,应用程序将流经 S1、S2,最后是 S3。但在现实生活中,事情永远不会那么顺利。 P1可能遇到错误,或者P2可能遇到错误,触发E1或E2。
考虑以下情况:
• 我们从P1 中的服务器收到成功响应,但返回的数据不正确,或者服务器上没有可用数据(认为是空数组)。在这种情况下,对于下一个承诺 P2,它应该触发错误处理程序 E2。
• 我们收到承诺P2 的错误,触发了E2。但是在处理程序内部,我们有来自缓存的数据,确保应用程序可以正常加载。在这种情况下,我们可能希望确保在 E2 之后调用 S3。
因此,每次我们编写成功或错误处理程序时,我们都需要进行调用——给定我们当前的函数,对于承诺链中的下一个处理程序,这个承诺是成功还是失败?
如果我们想为链中的下一个承诺触发成功处理程序,我们可以从成功或错误处理程序返回一个值
另一方面,如果我们想为链中的下一个承诺触发错误处理程序,我们可以使用
deferred
对象并调用其reject()
方法来做到这一点Jquery 中的延迟对象: https ://api.jquery.com/jquery.deferred/
AngularJs 中的延迟对象: https ://docs.angularjs.org/api/ng/service/ $q