Promise用法
let p = new Promise((resolve, reject) => {
resolve('success')
})
console.log(p)

let p = new Promise((resolve, reject) => {
// resolve('success')
reject('error')
})
console.log(p)

// then :返还值;1.没有返还 2.返还普通值;3.返还promise对象;
// 总结:返还promise对象--->链式操作;
let p = new Promise((resolve, reject) => {
resolve('success')
})
let res = p.then(res => {
// console.log(111)
})
console.log(res)

let p = new Promise((resolve, reject) => {
resolve('success')
})
let res = p.then(res => {
return 111
})
console.log(res)

let p = new Promise((resolve, reject) => {
resolve('success')
})
let res = p.then(res => {
return new Promise((resolve, reject)=>{
resolve('111')
})
})
console.log(res)

手写Promise
原本Promise通过c实现,这里我们用js模拟
let p = new KPromise((resolve, reject) => {
// 调取的时候通过小括号执行,那么封装的内部会有一个函数
// 执行函数,并且改变状态和value值
// resolve('success')
reject('error')
})
队列里的函数如何依次执行
// axios Promise 中本身也是用这种方式实现
let arr = [function(){
console.log(1111);
},function(){
console.log(222);
},function(){
console.log(3333);
}];
let cb;
while(cb=arr.shift()){
cb();
}

宏任务微任务
-
js单线程,浏览器多线程。同步任务放入主线程,异步队列放入异步队列。主线程执行完毕后执行异步队列。
-
微任务:promise;MutationObserver; process.nextTick;
-
宏任务:setTimeout;setInterval
// 微任务先执行,再宏任务再产生微任务,再执行微任务
// 宏任务
setTimeout(() => {
console.log('top')
}, 0);
// 原本Promise是微任务,这里模拟是宏任务需要改写成微任务
let p = new KPromise((resolve, reject) => {
resolve('success111')
// reject('error111')
})
// 加入队列
p.then(res => {
console.log(res)
}, err => {
console.log(err)
})
class KPromise{
constructor(handle) {
this.status = 'pending';
this.value = undefined;
// 创建异步队列,then 里需要的
this.resolveQueue = [];
this.rejectQueue = [];
handle(this._resolve.bind(this), this._reject.bind(this))
}
_resolve(val){
this.status = 'resolved'
this.value = val
// 执行then里成功的回调
let run = () => {
let cb;
// console.log(this.resolveQueue) Obj无length
while(cb = this.resolveQueue.shift()) {
cb(val)
}
}
setTimeout(run, 0)
}
_reject(err) {
this.status = 'rejected'
this.value = err
// 执行then里失败的回调
let run = () => {
let cb;
while(cb = this.rejectQueue.shift()) {
cb(err)
}
}
setTimeout(run, 0)
}
// 把多个onResolved 及 onRejected放在队列里
then(onResolved, onRejected){
this.resolveQueue.push(onResolved)
this.rejectQueue.push(onRejected)
}
}

MutationObserver
let observer = new MutationObserver(function(){
console.log("微任务回调");
})
// 有属性变化会触发回调
observer.observe(document.body,{
attributes: true
})
document.body.setAttribute("kkb",Math.random());

改写成与Promise一致
class KPromise{
constructor(handle) {
this.status = 'pending';
this.value = undefined;
// 创建异步队列,then 里需要的
this.resolveQueue = [];
this.rejectQueue = [];
handle(this._resolve.bind(this), this._reject.bind(this))
}
_resolve(val){
// console.log(this) undefinded
this.status = 'resolved'
this.value = val
// 执行then里成功的回调
let run = () => {
let cb;
// console.log(this.resolveQueue) Obj无length
while(cb = this.resolveQueue.shift()) {
cb(val)
}
}
let observer = new MutationObserver(run)
observer.observe(document.body, {
attributes: true
})
document.body.setAttribute('kkb', Math.random())
}
_reject(err) {
this.status = 'rejected'
this.value = err
// 执行then里失败的回调
let run = () => {
let cb;
while(cb = this.rejectQueue.shift()) {
cb(err)
}
}
setTimeout(run, 0)
}
// 把多个onResolved 及 onRejected放在队列里
then(onResolved, onRejected){
this.resolveQueue.push(onResolved)
this.rejectQueue.push(onRejected)
}
}

then 创建队列
创建队列,执行先后导致队列为空
// 这样写会有问题,先执行了回调后加入队列
// this.resolveQueue 为 [ ]
let p = new KPromise((resolve, reject) => {
// 调取的时候通过小括号执行,那么封装的内部会有一个函数
// 执行函数,并且改变状态和value值
resolve('success111')
// 执行了回调
// reject('error111')
})
// 加入队列
p.then(res => {
console.log(res)
}, err => {
console.log(err)
})
class KPromise{
constructor(handle) {
this.status = 'pending';
this.value = undefined;
// 创建异步队列,then 里需要的
this.resolveQueue = [];
this.rejectQueue = [];
handle(this._resolve.bind(this), this._reject)
}
// 错误语法
// () => {
// }
_resolve(val){
// console.log(this) undefinded
this.status = 'resolved'
this.value = val
console.log(this.resolveQueue) // [ ]
// 执行then里成功的回调
let run = () => {
let cb;
while(cb = this.resolveQueue.shift()) {
cb(val)
}
}
// run()
// setTimeout(run, 0)
}
_reject(err) {
this.status = 'rejected'
this.value = err
// 执行then里失败的回调
}
// 把多个onResolved 及 onRejected放在队列里
then(onResolved, onRejected){
this.resolveQueue.push(onResolved)
this.rejectQueue.push(onRejected)
}
}
修改后的js
// 修改后的js,执行回调需要放到setTimeout中
class KPromise{
constructor(handle) {
this.status = 'pending';
this.value = undefined;
// 创建异步队列,then 里需要的
this.resolveQueue = [];
this.rejectQueue = [];
handle(this._resolve.bind(this), this._reject)
}
_resolve(val){
this.status = 'resolved'
this.value = val
// 执行then里成功的回调
let run = () => {
let cb;
// console.log(this.resolveQueue) Obj无length
while(cb = this.resolveQueue.shift()) {
cb(val)
}
}
setTimeout(run, 0)
}
_reject(err) {
this.status = 'rejected'
this.value = err
// 执行then里失败的回调
let run = () => {
let cb;
while(cb = this.rejectQueue.shift()) {
cb(err)
}
}
setTimeout(run, 0)
}
// 把多个onResolved 及 onRejected放在队列里
then(onResolved, onRejected){
this.resolveQueue.push(onResolved)
this.rejectQueue.push(onRejected)
}
}
全部代码
// 宏任务
// setTimeout(() => {
// console.log('top')
// }, 0);
// // 微任务
// let p = new KPromise((resolve, reject) => {
// // 调取的时候通过小括号执行,那么封装的内部会有一个函数
// // 执行函数,并且改变状态和value值
// // resolve('success111')
// // 执行了回调
// reject('error111')
// })
// // 加入队列
// p.then(res => {
// console.log(res)
// }, err => {
// console.log(err)
// })
// p.then(res => {
// console.log(res)
// }, err => {
// console.log(err)
// })
// console.log(p)
// 链式调用:then始终返回promise对象
// let response = p.then(res=>{
// return res
// // console.log("1",res)
// // return new KPromise((resolve, reject)=>{
// // resolve('111')
// // })
// }, err => {
// // console.log(err)
// })
// console.log(response)
// let p1 = KPromise.resolve('111')
// console.log(p1)
// let p2 = KPromise.reject('error')
// console.log(p2)
// let p1 = new KPromise((resolve) => {
// resolve(111)
// })
// let p2 = new KPromise((resolve) => {
// resolve(222)
// })
// KPromise.all([p1, p2]).then(res => {
// console.log(res)
// })
// KPromise.race([p1, p2]).then(res => {
// console.log(res)
// })
// console.log(p3)
let p = new KPromise((resolve,reject)=>{
reject("err...");
})
p.then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
// console.log(p)
class KPromise{
constructor(handle) {
this.status = 'pending';
this.value = undefined;
// 创建异步队列,then 里需要的
this.resolveQueue = [];
this.rejectQueue = [];
handle(this._resolve.bind(this), this._reject.bind(this))
}
// 错误语法
// () => {
// }
_resolve(val){
// console.log(val)
// console.log(this) undefinded
this.status = 'resolved'
this.value = val
// console.log(val)
// 执行then里成功的回调
let run = () => {
let cb;
// console.log(this.resolveQueue) Obj无length
while(cb = this.resolveQueue.shift()) {
cb(val)
}
}
let observer = new MutationObserver(run)
observer.observe(document.body, {
attributes: true
})
document.body.setAttribute('kkb', Math.random())
// setTimeout(run, 0)
}
_reject(err) {
this.status = 'rejected'
this.value = err
// console.log(err)
// 执行then里失败的回调
let run = () => {
let cb;
while(cb = this.rejectQueue.shift()) {
cb(err)
}
}
let observer = new MutationObserver(run)
observer.observe(document.body, {
attributes: true
})
document.body.setAttribute('kkb', Math.random())
// setTimeout(run, 0)
}
// then :返还值;1.没有返还 2.返还普通值;3.返还promise对象; 总结:返还promise对象--->链式操作;
// 把多个onResolved 及 onRejected放在队列里
then(onResolved, onRejected){
// console.log(onResolved)
/**
* onResolved 接收传入的函数
*
(res)=>{
// return res
// console.log("1",res)
return new KPromise((resolve, reject)=>{
resolve('111')
})
}
*/
// this.resolveQueue.push(onResolved)
// this.rejectQueue.push(onRejected)
return new KPromise((resolve, reject) => {
this.resolveQueue.push(val => {
// console.log(val)
// 要拿到value onResolved 必须执行,执行后如果return 了Promise对象,那么val instanceof KPromise
// val 为then 第一个参数的执行结果,需要重新被赋值
/**
* 无return 时,promise value 为undefined
* return res时,return 传入的val
*
* return promise 时 return val.then(resolve)
*/
let val1 = onResolved && onResolved(val)
// console.log(onResolved && onResolved(val))
// 如果then返还的是Promise对象
if(val1 instanceof KPromise) {
// return val 返回的是80行的kPromise, 再调取then
return val1.then(resolve)
}
// 普通值直接返还
resolve(val1)
})
this.rejectQueue.push(err => {
onRejected && onRejected(err)
reject(err)
})
})
}
static resolve(val) {
return new KPromise(resolve => {
resolve(val)
})
}
static reject(err) {
return new KPromise((resolve, reject) => {
reject(err)
})
}
static all(lists) {
return new KPromise((resolve, reject) => {
let arr = []
for(let i = 0; i < lists.length; i++) {
lists[i].then(res => {
console.log(res)
arr.push(res)
}, err => {
reject(err)
})
}
resolve(arr)
})
}
static race(lists) {
return new KPromise((resolve, reject) => {
for(let i = 0; i < lists.length; i++) {
lists[i].then(res => {
resolve(res)
}, err => {
reject(err)
})
}
})
}
catch(onRejected) {
console.log(onRejected)
this.then(undefined, onRejected)
}
}