Promise
理解Promise
- 本质是一个构造函数,使用的时候需要new Promise
- new的时候会触发执行器,执行器是同步的
- 执行器有两个函数
- resolve
- reject
- Promise的状态是padding、resolve、reject
- 过程是padding->resolved 一旦改变不能更改
- 过程是padding->rejected 一旦改变不能更改
- 不能反过来
.then
- 是异步的
- 有两个方法
- 第一个接受resolve的结果
- 第二个是处理错误
- 值得注意的是如果在.then里面处理了error,那么接下来的catch就不能捕获
.all
- 返回一个数组,按顺序执行,如果有一个失败,那么他就会变化rejected
- interable类型->Array Set Map
- 场景:使用多个异步任务并发运行,他的结果是创建的承诺之后使用,等待所有任务的完成
.rach
- 谁最先执行完成,那么就先返回执行结果
- 处理请求资源的响应时间
async和await
- async 的意思是当前这个异步函数与当前的程序是异步关系
- await 等待Promise对象产出的结果
链式调用
- 成功的条件
- then return 普通的Javascript value
- then return 新的promise成功态的结果 value
- 失败的条件
- then retuen 新的promise失败态的原因 reason
- then 抛出了异常 throw new Error
- Promise链式原理
- JavaScript jQuery return this
- then 不具备this
- 返回新的Promise
手写Promise源码部分
// 定义好每种状态 根据Promise A+ 文档
const PENDING = 'PENDING', // 等待
FULLFILLED = 'FULLFILLED', // 成功
REJECTED = 'REJECTED' // 失败
function resolvePromise(promise2, x, resolve, reject) {
console.log(promise2);
}
class MyPromise {
constructor(executor) {
this.status = PENDING; // 状态值
this.value = undefined; //
this.reason = undefined;
// 设置两个容器
this.onFullfilledCallbacks = [];
this.onRejectedCallbacks = [];
// 把resolve,reject 定义在内部
const resolve = (value) => {
// 判断pending状态 成功改变状态
if (this.status === PENDING) {
this.status = FULLFILLED
this.value = value
// 发布模式
this.onFullfilledCallbacks.forEach(fn => fn())
}
}
const reject = (reason) => {
// 判断pending状态 失败改变状态
if (this.status === PENDING) {
this.status = REJECTED
this.reason = reason
// 发布模式
this.onRejectedCallbacks.forEach(fn => fn())
}
}
// 处理捕获异常
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
// resolve,reject 定义在外面可能在原型上 只能访问一次
// .then 两个函数 onFullfilled onRejected 即 成功 or 失败 需要用status 来判断 然后传 相对应的值
then(onFullfilled, onRejected) {
// 定义一个promise2 用于返回 编写链式调用
/**
* 1.处理thorw new Error -> try catch
* 2.setTimeout 处理 不能访问promise2 因为还没new出来 先执行了下面的resolvePromise 源码是微任务 这里宏任务代替
*/
// x 不确定是普通值 还是promsie
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULLFILLED) {
setTimeout(() => {
try {
let x = onFullfilled(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
}
if (this.status === PENDING) {
// 订阅模式
this.onFullfilledCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFullfilled(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
})
// 订阅模式
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
})
}
})
return promise2
}
}
module.exports = MyPromise
处理resolvePromise
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<MyPromise>'))
}
if (typeof x === 'object' && x !== null || typeof x === 'function') {
try {
let then = x.then // throw error 用try catch
let called = false
if (typeof then === 'function') { // 这里认为他就是Promise
// 改变this指向 Promise 实例 有两个参数 即成功 失败的方法
then.call(x, (y) => {
if (called) return
called = true
// resolve(y) 递归处理多层嵌套
resolvePromise(promise2, y, resolve, reject)
}, (r) => {
if (called) return
called = true
reject(r)
})
} else {
resolve(x)
}
} catch (e) {
if (called) return
called = true
reject(e);
}
} else {
resolve(x)
}
}
处理不能渗透的问题
// 处理 .then().then().then() 不能渗透的问题 因为这是定义好的 所以 没定义的时候 需要给他一个值
onFullfilled = typeof onFullfilled === 'function' ? onFullfilled : value => value
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
catch语法糖
模拟then 的方法 第一个参数空即可
catch(errorCallback) {
return this.then(null, errorCallback)
}