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

我看到的代码是这样的:

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

then()来自哪里?

541480 次浏览

我猜doSome会返回这个,也就是myObj,它也有then方法。标准方法链接…

如果doSome不返回this,作为doSome执行的对象,请放心,它将返回具有then方法的某个对象…

正如@patrick指出的,标准js中没有then()

截至ECMAScript6

.then()方法已经包含在纯JavaScript的承诺中。

Mozilla的文档:

then()方法返回一个Promise。它有两个参数:callback

.

.

Promise对象定义为

Promise对象用于延迟和异步 计算。Promise表示未完成的操作

也就是说,Promise充当一个尚未计算,但将在将来解析的值的占位符。.then()函数用于在Promise被解析时关联将要在Promise上调用的函数——无论是成功还是失败。

之前ECMAScript6

据我所知,在javascript中没有内置的then()方法(在撰写本文时)。

无论doSome("task")返回的是什么,似乎都有一个名为then的方法。

如果你将doSome()的返回结果记录到控制台,你应该能够看到返回结果的属性。

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

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

".then()"函数广泛用于Windows 8 Store应用程序异步编程中的承诺对象。 据我所知,它在某种程度上类似于回调

在本文档中查找详细信息 http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx < / p >

当然,它也可以是任何其他已定义函数的名称。

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

promise是一种处理异步操作的模式。该承诺允许您调用一个名为“then”的方法,该方法允许您指定作为回调函数使用的函数。

更多信息请参见:http://wildermuth.com/2013/8/3/JavaScript_Promises

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

在JavaScript中处理异步调用的传统方法是使用回调。 假设我们必须给服务器打三个电话,一个接一个,来设置我们的 应用程序。使用回调,代码可能看起来像下面这样(假设 一个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
});
});
});
在本例中,我们首先获取服务器配置。在此基础上,我们进行取回 关于当前用户的信息,最后获取当前用户的项目列表 用户。每个xhrGET调用都接受一个回调函数,该函数在服务器 回应。< / p > 当然,嵌套层数越多,代码就越难阅读,调试, 维护、升级和基本工作。这通常被称为回调地狱。 同样,如果我们需要处理错误,我们可能需要向每个错误传递另一个函数 xhrGET调用,告诉它在发生错误时需要做什么。如果我们只想要一个 常见错误处理程序,这是不可能的。

Promise API是为了解决这个嵌套问题而设计的

.错误处理的问题

Promise API提出以下建议:

  1. 每个异步任务将返回一个promise对象。
  2. 每个promise对象将有一个then函数,该函数可以接受两个参数,success . success . promise
  3. . handler和error handler
  4. then函数中的成功错误处理程序将仅在一次之后调用
  5. .异步任务结束
  6. then函数还将返回promise,以允许链接多个调用。
  7. 每个处理程序(成功或错误)可以返回一个value,它将被传递给下一个处理程序 函数作为argument,在promises链中
  8. 如果处理程序返回promise(发出另一个异步请求),则下一个 处理程序(成功或错误)将只在请求完成后调用
所以前面的示例代码可能会转换为以下内容,使用 promises和$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
}
);

传播成功和错误

链接承诺是一种非常强大的技术,它可以让我们完成很多事情 功能,比如让服务进行服务器调用,对 数据,然后将处理后的数据返回给控制器。但是当我们处理 promise链,有几件事我们需要记住 考虑下面有三个承诺的假设promise链,P1, P2和P3。 每个promise都有一个成功处理程序和一个错误处理程序,因此S1和E1用于P1, S2和 P2为E2, P3为S3和E3:

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

在正常的流程中,如果没有错误,应用程序将运行 通过S1, S2,最后到S3。但在现实生活中,事情从来没有那么顺利。P1可能

.如果P2遇到错误,可能会触发E1或E2

考虑以下情况:

我们从P1中的服务器接收到一个成功的响应,但返回的数据不是 正确,或者服务器上没有可用数据(假设为空数组)。在这样一个 对于下一个承诺P2,它应该触发错误处理程序E2.

我们收到承诺P2的错误,触发了E2。但在处理器内部,我们有 缓存中的数据,确保应用程序可以正常加载。这样的话, 我们可能想要确保在E2之后,S3被调用 所以每次我们写一个成功或错误处理程序时,我们都需要做一个call-given 当前函数,这个承诺对于承诺中的下一个处理程序是成功还是失败 链吗?< / em > < / p > 如果我们想为链中的下一个promise触发成功处理程序,我们可以 返回成功或错误处理程序中的值

类中的下一个promise触发错误处理程序 chain,我们可以使用deferred对象并调用它的reject()方法

什么是递延对象?

jQuery中的延迟对象表示将被延迟的工作单元 稍后完成,通常是异步完成。一旦单位的工作 完成时,deferred对象可以设置为resolved或failed deferred对象包含一个promise对象。通过promise对象 您可以指定当工作单元完成时将发生什么。你 通过在promise对象上设置回调函数来实现

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

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

doSome("task")必须返回一个promise对象,而这个promise总是有一个then函数,所以你的代码就像这样

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

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

这是一个小JS_Fiddle。

然后是一个方法回调堆栈,在承诺被解决后可用,它是库的一部分,如jQuery,但现在在原生JavaScript中可用,下面是它如何工作的详细解释

你可以在原生JavaScript中做一个承诺:就像在jQuery中有承诺一样,每个承诺都可以堆叠,然后可以用Resolve和Reject回调调用,这就是你如何链式异步调用。

我从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}`)
})

定义::然后是用于解决异步回调的方法

这在ES6中引入

请在这里找到适当的文档Es6承诺

这是我为自己做的一个东西,用来弄清楚事情是如何运作的。我想其他人也会发现这个具体的例子很有用:

doit().then(function() { log('Now finally done!') });
log('---- But notice where this ends up!');


// For pedagogical reasons I originally wrote the following doit()-function so that
// it was clear that it is a promise. That way wasn't really a normal way to do
// it though, and therefore Slikts edited my answer. I therefore now want to remind
// you here that the return value of the following function is a promise, because
// it is an async function (every async function returns a promise).
async function doit() {
log('Calling someTimeConsumingThing');
await someTimeConsumingThing();
log('Ready with someTimeConsumingThing');
}


function someTimeConsumingThing() {
return new Promise(function(resolve,reject) {
setTimeout(resolve, 2000);
})
}


function log(txt) {
document.getElementById('msg').innerHTML += txt + '<br>'
}
<div id='msg'></div>

我大概晚了8年,嗯……不管怎样,我真的不知道then()做什么,但也许MDN可能有一个答案。实际上,我可能更懂一点。

这将显示你所需要的所有信息(希望如此)。除非有人已经发布了这个链接。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then < / p > 格式为promise.prototype.then() promise和prototype有点像变量,但不像javascript中的变量,我的意思是像navigator.getBattery().then()这样的东西,这个确实存在,但在web上很少使用,这个显示设备电池的状态,如果你好奇的话,MDN上的更多信息

它是关于在箭头函数中使用花括号{}的:


这3个例子都在做同样的事情(什么都没有,但是有有效的语法,并且是有效的承诺链!)


new Promise(function(ok) {
ok(
/* myFunc1(param1, param2, ..) */
)
}).then(function(){
/* myFunc1 succeed */
/* Launch something else */
/* console.log(whateverparam1) */
/* myFunc2(whateverparam1, otherparam, ..) */
}).then(function(){
/* myFunc2 succeed */
/* Launch something else */
/* myFunc3(whatever38, ..) */
})


console.log("This code has no errors GG!")


相同的逻辑使用箭头函数简写而没有{}

new Promise((ok) =>
ok(
/* myFunc1(param1, param2, ..) */
).then(() =>
0 // HEY DID YOU NOTICE! A number that does nothing,
// but otherwise the parsing will fail!
// The code is pretty clean but have a major downside
// As arrow functions without {} can contains only one declaration
// console.log("something") will FAIL here
).then(() =>
"" // HEY DID YOU NOTICE! An empty string that does nothing,
// but otherwise the parsing will fail!
// As arrow functions without {} can contains only one declaration
// We can't add more code here, hence:
// console.log("something")
// Will break the whole promise
// This is likely the error in y(our) code ;)
))


console.log("This code has no errors GG!")


带有{}的箭头函数

new Promise( (ok) => {
ok(
/* myFunc1(param1, param2, ..) */
)
}).then( () => {
/* myFunc1 succeed */
/* Launch something else */
}).then( () => {
/* myFunc2 succeed */
/* Launch something else */
/* myFunc3(whatever38, ..) */
console.log("something")
/* More console logs! */
console.log("something else")
})


console.log("This code has no errors GG!")

.then在async函数中返回一个promise。

好的例子是:

var doSome = new Promise(function(resolve, reject){
resolve('I am doing something');
});


doSome.then(function(value){
console.log(value);
});

要向它添加另一个逻辑,你还可以添加reject('I am the rejected param')调用函数和console.log。