一.promise的理解
1.Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了 Promise 对象。
2.所谓 Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
2.基本使用方法
(1).语法:
new Promise( function(resolve, reject) {...} /* executor */ )
(2).原理:
- 构建 Promise 对象时,需要传入一个 executor 函数,主要业务流程都在 executor 函数中执行。
- Promise构造函数执行时立即调用executor 函数, resolve 和 reject
两个函数作为参数传递给executor,resolve 和 reject
函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。一旦状态改变,就不会再变,任何时候都可以得到这个结果。 - 在 executor 函数中调用 resolve 函数后,会触发 promise.then 设置的回调函数;而调用 reject
函数后,会触发 promise.catch 设置的回调函数。
如下图所示:
romise 是用来管理异步编程的,它本身不是异步的,new Promise的时候会立即把executor函数执行,只不过我们一般会在executor函数中处理一个异步操作。
比如下面代码中,一开始是会先打印出2:
let p1 = new Promise(()=>{
setTimeout(()=>{
console.log(1)
},1000)
console.log(2)
})
console.log(3) // 2 3 1
4.Promise 采用了回调函数延迟绑定技术,在执行 resolve 函数的时候,回调函数还没有绑定,那么只能推迟回调函数的执行。
如下所示:
eg:
let p1 = new Promise((resolve,reject)=>{
console.log(1);
resolve('我吃好了')//成功状态
console.log(2)
})
// then:设置成功或者失败后处理的方法
p1.then(result=>{
//p1延迟绑定回调函数
console.log('成功 '+result)
},reason=>{
console.log('失败 '+reason)
})
console.log(3)
// 1
// 2
// 3
// 成功 我吃好了
解析:
new Promise的时候先执行executor函数,打印出 1、2,Promise在执行resolve时,触发微任务,还是继续往下执行同步任务, 执行p1.then时,存储起来两个函数(此时这两个函数还没有执行),然后打印出3,此时同步任务执行完成,最后执行刚刚那个微任务,从而执行.then中成功的方法。
5.扩展:
async 和 await:
(1).ES7中新增的异步编程方法,async/await的实现是基于 Promise的,简单而言就是async 函数就是返回Promise对象,是generator的语法糖。
很多人认为async/await是异步操作的终极解决方案:
语法简洁,更像是同步代码,也更符合普通的阅读习惯;
改进JS中异步操作串行执行的代码组织方式,减少callback的嵌套;
Promise中不能自定义使用try/catch进行错误捕获,但是在Async/await中可以像处理同步代码处理错误。
(2).举例子说明:
let p1 = Promise.resolve(1)
let p2 = new Promise(resolve => {
setTimeout(() => {
resolve(2)
}, 1000)
})
async function fn() {
console.log(1)
// 当代码执行到此行(先把此行),构建一个异步的微任务
// 等待promise返回结果,并且await下面的代码也都被列到任务队列中
let result1 = await p2
console.log(3)
let result2 = await p1
console.log(4)
}
fn()
console.log(2)
// 1 2 3 4
解析:
如果 await 右侧表达逻辑是个 promise,await会等待这个promise的返回结果,只有返回的状态是resolved情况,才会把结果返回,如果promise是失败状态,则await不会接收其返回结果,await下面的代码也不会在继续执行