目录
一、什么是Promise
A Promise is an object representing the eventual completion or failure of an asynchronous operation.
从官方文档我们可知
- Promise是ES6新增的一个对象,一个构造函数。
- 用于多层次异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数地狱问题。
promise主要是用来解决回调地狱的问题,通过使用.then来使得代码成链式调用,方便维护和使用。.then中的回调函数属于异步任务中的微任务。
1.1 Promise的三种状态
- pending: 初始状态,既不是成功,也不是失败状态。
- fulfilled: 意味着操作成功完成。——注:fulfilled 或称 resolved
- rejected: 意味着操作失败。
什么意思呢?三种状态对应异步操作的三种情况,比如发送一次ajax请求,初始等待时,状态为pending;ajax请求成功时,调用Promise内置函数resolve(), Promise状态 => fulfilled;请求失败时,调用函数reject(),Promise状态 => rejected。
Promise是异步编程的一种解决方案,它的构造函数是同步执行的,then 方法是异步执行的,所以Promise创建后里面的函数会立即执行,构造函数中的resolve和reject只有第一次执行有效,也就是说Promise状态一旦改变就不能再变
二、Promise 基本用法
var Promise: PromiseConstructor
new <any>(executor: (resolve: (value?: any) => void, reject: (reason?: any) => void) => void) => Promise<any>
从语法上来看,Promise 是一个构造函数,需要传入一个参数 executor函数。
new Promise 时会调用 executor 函数, executor 函数也有两个参数 resolve 和 reject,这两个参数也是函数,调用 resolve 或 reject 时,分别将promise的状态改为fulfilled(完成)或 rejected(失败)。Promise 状态只能唯一。
2.1 Promise基本使用
下面来看两个例子
(1) 用流程控制的分支结构,判断异步请求是否成功
var promise = new Promise((resolve, reject) => {
if(异步请求成功){
resolve()
}else{
reject()
}
})
promise.then(()=>{
//success
},()=>{
//failure
})
(2) 用定时器setTimeout模拟异步请求成功
function ajax() {
return new Promise(resolve => {
setTimeout(resolve, 1000)
})
}
ajax().then(() => {
console.log("request success") //success
})
上面代码表示,如果异步操作成功,就调用resolve()方法,就会执行Promise实例的then()方法的第一个回调函数,如果失败则调用Promise实例的then()方法的第二个回调函数。
2.2 Promise使用时传参
resolve() 和 reject() 函数调用时可传参,传入的参数会被Promise实例的 then 和 catch 方法捕获。
var promise = new Promise((resolve, reject) => {
if (异步请求成功) {
resolve("success")
} else {
reject("error")
}
})
promise.then( res => {
res // success
})
//捕获异常可用catch()方法
promise.catch( err => {
err // error
})
我们来执行一下,看看结果:
2.3 Promise 链式调用
Promise强大的地方在于此,如果发送一个异步请求,又返回另外一个异步请求时,可用链式调用
new Promise((resolve) => {
resolve(1)
}).then((res) => {
return new Promise((resolve) => {
resolve(res+2)
})
}).then((res) => {
return new Promise((resolve) => {
resolve(res+3)
})
}).then((res) => {
return res // 6
})
当对异步请求返回结果 res 的简单操作时,可用 Promise.resolve() 简写
new Promise((resolve) => {
resolve(1)
}).then((res) => {
return Promise.resolve(res+2)
}).then((res) => {
return Promise.resolve(res+3)
}).then((res) => {
return res // 6
})
还有一种更简单的语法糖
new Promise((resolve) => {
resolve(1)
}).then((res) => {
return res + 2
}).then((res) => {
return res + 3
}).then((res) => {
return res // 6
})
运行结果:
2.4 链式调用注意事项
链式调用(chaining)按序执行,有以下约定,使用时要多注意。
- 在本轮 事件循环运行完成之前,回调函数是不会被调用的。
- 即使异步操作已经完成(成功或失败),在这之后通过 then()添加的回调函数也会被调用
- 通过多次调用then() 可以添加多个回调函数,它们会按照插入顺序执行
看下面的例子
new Promise((resolve) => {
resolve()
}).then(() => {
console.log('execute') // execute
}).then(() => {
console.log('execute1') // execute
}).then(() => {
console.log('execute2') // execute
})
我们来看看,运行结果: