在线文档教程

promise.then

promise.then

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

如果忽略针对某个状态的回调函数参数,或者提供非函数 (nonfunction) 参数,那么 then 方法将会丢失关于该状态的回调函数信息,但是并不会产生错误。如果调用 thenPromise 的状态(fulfillment 或 rejection)发生改变,但是 then 中并没有关于这种状态的回调函数,那么 then 将创建一个没有经过回调函数处理的新 Promise 对象,这个新 Promise 只是简单地接受调用这个 then的原 Promise 的终态作为它的终态。

语法

p.then(onFulfilled[, onRejected] p.then(function(value) { // fulfillment }, function(reason) { // rejection }

参数

onFulfilled当Promise变成接受状态(fulfillment)时,该参数作为回调函数被调用(参考: Function)。该函数有一个参数,即接受的值(the fulfillment  value)。onRejected当Promise变成拒绝状态(rejection )时,该参数作为回调函数被调用(参考: Function)。该函数有一个参数,,即拒绝的原因(the rejection reason)

返回值

then方法返回一个Promise,而它的行为与then中的回调函数的返回值有关:

  • 如果then中的回调函数返回一个值,那么then返回的Promise将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。

  • 如果then中的回调函数抛出一个错误,那么then返回的Promise将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。

  • 如果then中的回调函数返回一个已经是接受状态的Promise,那么then返回的Promise也会成为接受状态,并且将那个Promise的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。

  • 如果then中的回调函数返回一个已经是拒绝状态的Promise,那么then返回的Promise也会成为拒绝状态,并且将那个Promise的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。

  • 如果then中的回调函数返回一个未定状态(pending)的Promise,那么then返回Promise的状态也是未定的,并且它的终态与那个Promise的终态相同;同时,它变为终态时调用的回调函数参数与那个Promise变为终态时的回调函数的参数是相同的。

以下举例说明该then方法的异步性。

// using a resolved promise, the 'then' block will be triggered instantly, but its handlers will be triggered asynchronously as demonstrated by the console.logs var resolvedProm = Promise.resolve(33 var thenProm = resolvedProm.then(function(value){     console.log("this gets called after the end of the main stack. the value received and returned is: " + value     return value; } // instantly logging the value of thenProm console.log(thenProm // using setTimeout we can postpone the execution of a function to the moment the stack is empty setTimeout(function(){     console.log(thenProm } // logs, in order: // Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined} // "this gets called after the end of the main stack. the value received and returned is: 33" // Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 33}

描述

由于 then 和 Promise.prototype.catch()方法都会返回 promise,它们可以被链式调用 — 一种称为复合( composition) 的操作.

示例

使用then方法

var p1 = new Promise( (resolve, reject) => { resolve('Success!' // or // reject ("Error!" } p1.then( value => { console.log(value // Success! }, reason => { console.log(reason // Error! }

链式调用

then 方法返回一个Promise 对象,其允许方法链。

你可以传递一个 lambda 给 then 并且如果它返回一个 promise,一个等价的 Promise 将暴露给后续的方法链。下面的代码片段使用 setTimout 函数来模拟异步代码操作。

Promise.resolve('foo') // 1. Receive "foo", concatenate "bar" to it, and resolve that to the next then .then(function(string) { return new Promise(function(resolve, reject) { setTimeout(function() { string += 'bar'; resolve(string }, 1 } }) // 2. receive "foobar", register a callback function to work on that string // and print it to the console, but not before returning the unworked on // string to the next then .then(function(string) { setTimeout(function() { string += 'baz'; console.log(string }, 1) return string; }) // 3. print helpful messages about how the code in this section will be run // before the string is actually processed by the mocked asynchronous code in the // previous then block. .then(function(string) { console.log("Last Then: oops... didn't bother to instantiate and return " + "a promise in the prior then so the sequence may be a bit " + "surprising" // Note that `string` will not have the 'baz' bit of it at this point. This // is because we mocked that to happen asynchronously with a setTimeout function console.log(string }

当一个值只是从一个then内部返回时,它将有效地返回 Promise.resolve(<由被调用的处理程序返回的值>)。

var p2 = new Promise(function(resolve, reject) { resolve(1 } p2.then(function(value) { console.log(value // 1 return value + 1; }).then(function(value) { console.log(value + '- This synchronous usage is virtually pointless' // 2- This synchronous usage is virtually pointless } p2.then(function(value) { console.log(value // 1 }

如果函数抛出错误或返回一个拒绝的承诺,则调用将返回一个拒绝的承诺。

Promise.resolve() .then( () => { // Makes .then() return a rejected promise throw 'Oh no!'; }) .then( () => { console.log( 'Not called.' }, reason => { console.error( 'onRejected function called: ', reason }

在其他情况下,一个 resolving Promise 会被返回。在下面的例子里,第一个 then() 会返回一个用 resolving Promise 包装的 42,即使之前的 Promise 是 rejected 的。

Promise.reject() .then( () => 99, () => 42 ) // onRejected returns 42 which is wrapped in a resolving Promise .then( solution => console.log( 'Resolved with ' + solution ) // Resolved with 42

实际上,捕获 rejected promise 的需求经常大于使用 then 的两种情况语法,比如下面这样的:

Promise.resolve() .then( () => { // Makes .then() return a rejected promise throw 'Oh no!'; }) .catch( reason => { console.error( 'onRejected function called: ', reason }) .then( () => { console.log( "I am always called even if the prior then's promise rejects" }

你也可以在另一个顶层函数上使用链式去实现带有 Promise-based API 的函数。

function fetch_current_data() { // The fetch() API returns a Promise. This function // exposes a similar API, except the fulfillment // value of this function's Promise has had more // work done on it. return fetch('current-data.json').then((response) => { if (response.headers.get('content-type') != 'application/json') { throw new TypeError( } var j = response.json( // maybe do something with j return j; // fulfillment value given to user of // fetch_current_data().then() } }

如果onFulfilled返回了一个 promise,then的返回值就会被 Promise resolved或者rejected。

function resolveLater(resolve, reject) { setTimeout(function () { resolve(10 }, 1000 } function rejectLater(resolve, reject) { setTimeout(function () { reject(20 }, 1000 } var p1 = Promise.resolve('foo' var p2 = p1.then(function() { // Return promise here, that will be resolved to 10 after 1 second return new Promise(resolveLater } p2.then(function(v) { console.log('resolved', v // "resolved", 10 }, function(e) { // not called console.log('rejected', e } var p3 = p1.then(function() { // Return promise here, that will be rejected with 20 after 1 second return new Promise(rejectLater } p3.then(function(v) { // not called console.log('resolved', v }, function(e) { console.log('rejected', e // "rejected", 20 }

规范

SpecificationStatusComment
ECMAScript 2015 (6th Edition, ECMA-262)The definition of 'Promise.prototype.then' in that specification.StandardInitial definition in an ECMA standard.
ECMAScript Latest Draft (ECMA-262)The definition of 'Promise.prototype.then' in that specification.Living Standard

浏览器兼容性

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Basic Support32.0(Yes)29.0No197.1

FeatureAndroidChrome for AndroidEdge mobileFirefox for AndroidIE mobileOpera AndroidiOS Safari
Basic Support4.4.432.0(Yes)29No(Yes)8.0