总结
- await只能在async函数中使用,不然会报错
- async函数返回的是一个Promise对象,有无值看有无return值
- await后面最好是接Promise,虽然接其他值也能达到排队效果
- async/await作用是用同步方式,执行异步操作
实现promise
- 1、执行了resolve,Promise状态会变成fulfilled
- 2、执行了reject,Promise状态会变成rejected
- 3、Promise只以第一次为准,第一次成功就永久为fulfilled,第一次失败就永远状态为rejected
- 4、Promise中有throw的话,就相当于执行了reject
- 5、promise中有三个状态:pending,fulfilled以及rejected
- 6、Promise中有throw的话,就相当于执行了reject。这就要使用try catch了
实现then
实现then:
1.Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
2.then接收两个回调,一个是成功回调,一个是失败回调
- 当Promise状态为fulfilled执行成功回调,为rejected执行失败回调
- 如resolve或reject在定时器里,则定时器结束后再执行then
promise构造函数是同步执行的,then方法本身是同步执行,then方法中的内容加入微任务异步执行
我们不能确保1秒后才执行then函数,但是我们可以保证1秒后再执行then里的回调,我们可以先把
then里的两个回调保存起来,然后等到1秒过后,当执行了resolve或者reject,咱们再去判断状态,
并且判断要去执行刚刚保存的两个回调中的哪一个回调
那么问题来了,我们怎么知道当前1秒还没走完甚至还没开始走呢?其实很好判断,只要状态是pending,
那就证明定时器还没跑完,因为如果定时器跑完的话,那状态肯定就不是pending,而是fulfilled或者
rejected那是用什么来保存这些回调呢?建议使用数组,因为一个promise实例可能会多次then,用数组
就一个一个保存了
图片:https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5a1a39ceb21241bbb6394e3083da00e3~tplv-k3u1fbpfcp-watermark.image?
参考:https://juejin.cn/post/6994594642280857630#heading-1
- then支持链式调用,下一次then执行受上一次then返回值的影响 【未实现】
1、then方法本身会返回一个新的Promise对象
2、如果返回值是promise对象,返回值为成功,新promise就是成功
3、如果返回值是promise对象,返回值为失败,新promise就是失败
4、如果返回值非promise对象,新promise对象就是成功,值为此返回值
5、then函数默认返回一个promise对象,值是undefined 默认是成功的
咱们知道then是Promise上的方法,那如何实现then完还能再then呢?
很简单,then执行后返回一个Promise对象就行了,就能保证then完还能继续执行then:
图片:https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3653db740a674f0192fca66987953e0c~tplv-k3u1fbpfcp-watermark.image?
promise.then(function(value) {
// success
}, function(error) {
// failure
});
代码实现
// 实现promise class基本版
class myPromise {
constructor(callback) {
// 返回的值
this.promiseState = "pending"
this.promiseResult = undefined
this.onFulfilledCallbacks = [] // 保存成功回调
this.onRejectedCallbacks = [] // 保存失败回调
// 执行传进来的函数 修正指向
callback(this.resolve.bind(this), this.reject.bind(this)) // 函数如果直接调用,函数内的this是window
}
// resolve
resolve(value) {
// state是不可变的
if (this.promiseState !== 'pending') return
this.promiseState = "fulfilled" // 如果执行resolve,状态变为fulfilled
this.promiseResult = value // 终值为传进来的值
// 定时器情形
while (this.onFulfilledCallbacks.length) { // 如果任务队列中长度不为0 那么一直调用该方法
this.onFulfilledCallbacks.shift()(this.promiseResult) // 先进先出 从前面删除一位 返回那一位
}
}
// reject
reject(err) {
if (this.promiseState !== 'pending') return
this.promiseState = "rejected"
this.promiseResult = err
// 定时器情形
while (this.onFulfilledCallbacks.length) { // 如果任务队列中长度不为0 那么一直调用该方法
this.onFulfilledCallbacks.shift()(this.promiseResult) // 先进先出 从前面删除一位
}
}
// then
then(onFulfilled, onRejected) { // 实例调用他 自然会有this
// 参数检验,一定是函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val // 随便一个箭头函数
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
// 执行回调函数
if (this.promiseState === 'fulfilled') { // 如果当前为成功状态,执行第一个回调
onFulfilled(this.promiseResult)
} else if (this.promiseState === 'rejected') { // 如果当前为失败状态,执行第二哥回调
onRejected(this.promiseResult)
} else if(this.promiseState === 'pending'){ // 定时器情况 执行了then函数依然是pending情况
this.onFulfilledCallbacks.push(onFulfilled.bind(this)) // 爸他们丢进任务队列中
this.onRejectedCallbacks.push(onRejected.bind(this))
}
}
}
// 调用手写的myPromise
let result = new myPromise(function (resolve, reject) {
// 普通情况
// resolve("我成功了")
// reject("我失败了")
// 定时器情况
setTimeout(() => {
resolve("我成功了")
}, 1000);
})
console.log(result)
result.then(res=>{
console.log(res)
})