JavaScript中的函数then()是什么意思?

我看到的代码如下所示:

myObj.doSome("task").then(function(env) { // logic }); 

那么()从哪里来?

在JavaScript中处理asynchronous调用的传统方式是使用callback函数。 比方说,我们必须三次打电话给服务器,一个接一个地设置我们的应用程序。 通过callback,代码可能如下所示(假设一个xhrGET函数来调用服务器):

 // Fetch some server configuration xhrGET('/api/server-config', function(config) { // Fetch the user information, if he's logged in xhrGET('/api/' + config.USER_END_POINT, function(user) { // Fetch the items for the user xhrGET('/api/' + user.id + '/items', function(items) { // Actually display the items here }); }); }); 

在这个例子中,我们首先获取服务器configuration。 然后基于此,我们获取有关当前用户的信息,最后得到当前用户的项目列表。 每个xhrGET调用都会在服务器响应时执行一个callback函数。

当然,我们拥有的嵌套层次越多,代码就越难读取,debugging,维护,升级,基本上工作。 这通常被称为回拨地狱。 另外,如果我们需要处理错误,我们需要将另一个函数传递给每个xhrGET调用,以告诉它在出错时需要做什么。 如果我们只想要一个常见的error handling程序,那是不可能的。

Promise API旨在解决这个嵌套问题和error handling的问题。

Promise API提出以下build议:

  1. 每个asynchronous任务将返回一个promise对象。
  2. 每个promise对象都有一个可以接受两个参数的函数,一个success处理函数和一个error处理函数。
  3. 在asynchronous任务完成后, then函数中的成功error handling程序将只被调用一次
  4. then函数也将返回一个promise ,以允许链接多个调用。
  5. 每个处理程序(成功或错误)都可以返回一个value ,这个value将在promise的链中作为argument传递给下一个函数。
  6. 如果处理程序返回一个promise (发出另一个asynchronous请求),则只有在请求完成后才会调用下一个处理程序(成功或错误)。

所以前面的示例代码可能会翻译成如下所示,使用promise和$http服务(在AngularJs中):

 $http.get('/api/server-config').then( function(configResponse) { return $http.get('/api/' + configResponse.data.USER_END_POINT); } ).then( function(userResponse) { return $http.get('/api/' + userResponse.data.id + '/items'); } ).then( function(itemResponse) { // Display items here }, function(error) { // Common error handling } ); 

传播成功与错误

链接承诺是一个非常强大的技术,它使我们能够完成许多function,例如让服务进行服务器调用,对数据进行一些后处理,然后将处理后的数据返回给控制器。 但是,当我们使用promise链时,我们需要记住一些事情。

考虑以下三个承诺P1,P2和P3的假设promise链。 每个promise都有一个成功处理程序和一个error handling程序,因此S1和E1代表P1,S2和E2代表P2,S3和E3代表P3:

 xhrCall() .then(S1, E1) //P1 .then(S2, E2) //P2 .then(S3, E3) //P3 

在正常的事物stream中,没有错误的地方,应用程序将stream过S1,S2,最后是S3。 但在现实生活中,事情并不那么顺利。 P1可能会遇到错误,或P2可能会遇到错误,触发E1或E2。

考虑以下情况:

•我们在P1中从服务器收到成功的响应,但是返回的数据不正确,或者服务器上没有可用的数据(认为是空arrays)。 在这种情况下,对于下一个承诺P2,它应该触发error handling程序E2。

•我们收到承诺P2的错误,触发E2。 但是在处理程序中,我们有来自caching的数据,确保应用程序可以正常加载。 在这种情况下,我们可能要确保在E2之后,S3被调用。

所以每次我们写一个成功或者一个error handling程序,我们都需要打一个电话给定我们当前的function,这个承诺对于承诺链中的下一个处理程序是成功还是失败?

如果我们想要触发链中下一个承诺的成功处理程序,我们可以从成功或error handling程序返回一个值

另一方面,如果我们想要为链中的下一个承诺触发error handling程序,我们可以使用deferred对象并调用其reject()方法

现在什么是延期对象?

jQuery中的延迟对象表示将在稍后完成的工作单元,通常是asynchronous的。 一旦工作单元完成,可以将deferred对象设置为已解决或失败。

deferred对象包含一个promise对象。 通过promise对象,您可以指定在工作单元完成时将发生的事情。 您可以通过在promise对象上设置callback函数来实现。

JQuery中的延迟对象: https : //api.jquery.com/jquery.deferred/

AngularJs中的延迟对象: https ://docs.angularjs.org/api/ng/service/ $ q

那么()函数与在某些库或框架(如jQuery或AngularJS)中使用的“Javascript承诺”相关。

承诺是处理asynchronous操作的模式。 promise允许你调用一个叫做“then”的方法,让你指定函数作为callback函数。

有关更多信息,请参阅: http : //wildermuth.com/2013/8/3/JavaScript_Promises

对于Angular的承诺: http : //liamkaufman.com/blog/2013/09/09/using-angularjs-promises/

据我所知, javascript没有内build的then()方法(在写这篇文章的时候)。

看来无论是doSome("task")返回的是一个叫做then的方法。

如果将doSome()的返回结果logging到控制台,应该可以看到返回的属性。

 console.log( myObj.doSome("task") ); // Expand the returned object in the // console to see its properties. 

更新(从ECMAScript6开始) : –

.then()函数已经包含在纯javascript中。

从这里的Mozilla文档中,

then()方法返回一个Promise。 它有两个参数:Promise的成功和失败情况的callback函数。

Promise对象又被定义为

Promise对象用于延迟和asynchronous计算。 Promise代表尚未完成的操作,但预计在未来。

也就是说, Promise作为一个尚未计算的价值的占位符,但将在未来得到解决。 .then()函数用于关联在parsing时要在Promise上调用的函数 – 无论是成功还是失败。

我怀疑doSome返回这个,这是myObj,它也有一个方法。 标准方法链接…

如果doSome没有返回这个,作为doSome被执行的对象,放心它正在返回一个对象与一个then方法…

正如@帕特里克指出的那样,没有那么标准的js

这是一个小JS_Fiddle。

然后是一个方法callback堆栈,这是一个承诺解决后可用它是像jQuery图书馆的一部分,但现在它是在原生JavaScript中可用,下面是它的工作原理的详细说明

你可以在原生JavaScript中做一个Promise:就像在jQuery中有承诺一样,每个promise都可以被堆栈,然后可以通过Resolve和Rejectcallback来调用,这就是你如何链接asynchronous调用。

我分叉和编辑从MSDN文档电池充电状态..

这样做是试图找出用户笔记本电脑或设备是否正在充电电池。 然后被调用,你可以做你的工作发布成功。

 navigator .getBattery() .then(function(battery) { var charging = battery.charging; alert(charging); }) .then(function(){alert("YeoMan : SINGH is King !!");}); 

另一个es6例子

 function fetchAsync (url, timeout, onData, onError) { … } let fetchPromised = (url, timeout) => { return new Promise((resolve, reject) => { fetchAsync(url, timeout, resolve, reject) }) } Promise.all([ fetchPromised("http://backend/foo.txt", 500), fetchPromised("http://backend/bar.txt", 500), fetchPromised("http://backend/baz.txt", 500) ]).then((data) => { let [ foo, bar, baz ] = data console.log(`success: foo=${foo} bar=${bar} baz=${baz}`) }, (err) => { console.log(`error: ${err}`) }) 

定义:: 然后是一个用来解决asynchronouscallback的方法

这是在ES6中引入的

请在这里find适当的文件Es6承诺

对于Windows 8商店应用程序,Asynchoronus编程中的“.then()”函数被广泛用于承诺的对象。 据我了解,它有点像callback。

查找此文档中的详细信息http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx

因为它也可以是任何其他定义函数的名称。

在这种情况下, then()doSome()方法返回的对象的类方法。

doSome(“task”)必须返回一个promise对象,并且这个promise有一个then函数。所以你的代码就像这样

 promise.then(function(env) { // logic }); 

你知道这只是一个普通的成员函数调用。