1. Promise是什么?
Promise是用来解决异步编程的一个方法,它是一个对象,用来生成promise实例。
Promise对象有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)。
2. 一个简单的Promise示例
var promiseExample = new Promise ((resolve, reject) => {
setTimeout (() => {
resolve('成功')
}, 1000)
})
promiseExample.then ((res) => {
console.log(res)
})
// 成功
Promise对象的参数是一个函数,该函数的两个参数为resolve和reject,两个参数是两个函数。
resolve的作用是将Promise对象的状态从 “进行中” 变成 “成功” (pending–resolved),在异步成功时调用,并将异步结果作为参数传递出去;
reject的作用是将Promise对象的状态从 “进行中” 变成 “失败” (pending–rejected),在异步失败时调用,并将异步错误作为参数传递出去。
promise实例创建后,then方法可以用来为resolved和rejected状态指定回调函数,then可以接受两个回调函数,分别是promise实例的状态变为resolved和rejected时调用。第二个参数是可选的,不一定要提供。这两个函数都接受promise对象传出的值作为参数。
3. 执行顺序
Promise新建后会立即执行。以下用一个简单示例让大家来了解:
let promise = new Promise ((resolve, reject) => {
console.log('我是promise内部语句~')
resolve('resolve')
console.log('我是resolve后语句~')
})
promise.then(res => {
console.log(res)
})
console.log('我是外部输出语句~')
结果为:
以上结果可以看出,promise创建后立即执行,then方法的回调函数会在当前脚本所有同步代码执行完后执行,所以最后输出resolve。
还可以看出,resolve并不会阻断promise内部代码执行,不过,一般resolve或者reject后,promise的任务就执行完毕了,其后的代码应该放到then中执行,可在resolve或reject前加上return,以防万一。
4. resolve的参数是另一个promise的情况
resolve和reject函数若是带有参数,参数会被传递给回调函数,即then方法接受的两个函数。reject函数的参数通常是Error对象的实例,表示抛出的错误,resolve函数的值除了正常值外,还可以是另一个promise。
若promiseB的resolve函数的参数是promiseA,则promiseB的状态被promiseA的状态决定。如下面这种情况:
const promiseA = new Promise(function (resolve, reject) {
})
const promiseB = new Promise(function (resolve, reject) {
resolve(promiseA)
})
如果promiseA的状态是pending,则promiseB的回调函数会等待promiseA的状态改变;如果promiseA的状态已经是resolved或rejected,promiseB的回调函数将会立即执行。
以下是一个例子:
const promiseA = new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('fail')), 3000)
})
const promiseB = new Promise(function (resolve, reject) {
setTimeout(() => resolve(promiseA), 1000)
})
promiseB
.then(result => console.log(result))
.catch(error => console.log(error))
如上,promiseB的resolve函数的参数是promiseA,promiseA的状态在3秒后变成rejected。promiseB的状态在1秒后变成resolved,promiseB的状态由promiseA决定,then语句变成针对promiseA,不输出,2秒后,promiseA变为rejected,触发catch方法。