feat: 手写Promise初始版本
This commit is contained in:
parent
defec92bf7
commit
bb2ac051a1
78
js/js异步.js
Normal file
78
js/js异步.js
Normal file
@ -0,0 +1,78 @@
|
||||
// js 是由于要处理dom故js在设计之初就是单线程,单线程在处理异步问题上不能像其他语言那样,
|
||||
// 直接创建线程交给线程执行,之后通知给主线程,甚至都不用通知,自己直接就解决掉,但是js不行
|
||||
// js在处理异步任务时不是自己解决的,自己只是等一个结果,其他都油宿主环境解决。
|
||||
|
||||
// js代码分同步代码和异步代码,同步代码,就是我们写的如:循环,判断,赋值等,那么异步代码又是什么
|
||||
// 如各类事件,setTimeout, setInterval, ajax都是异步的,这些代码不会立即执行,要等宿主环境触发
|
||||
// 事件才会执行,如果不触发js会一直等吗?显然不会,js是单线程的,如果等待事件那岂不是阻塞ui了,那界面不久
|
||||
// 卡住了吗!所以js有一种处理事件的机制叫做Event Loop(事件循环)
|
||||
|
||||
// 看下面的代码执行顺序
|
||||
// console.log(1);
|
||||
// setTimeout(function(){
|
||||
// console.log(2);
|
||||
// },0)
|
||||
// console.log(3);
|
||||
// new Promise(resolve=>{
|
||||
// console.log(4);
|
||||
// resolve(1)
|
||||
// }).then(res=>{
|
||||
// console.log(5);
|
||||
// })
|
||||
|
||||
// 执行顺序不是1,2,3,4,5,而是1,3,4,5,2,这是由于js会优先执行同步代码,当同步代码执行完成之后
|
||||
// 会查看有没有微任务,如果有,就把微任务放到执行栈里面执行,执行完微任务之后再看宏任务队列里面有没任务,
|
||||
// 如果有的话就把宏任务放到执行栈里面执行,知道全部执行完毕
|
||||
|
||||
|
||||
// 手写一个Promise
|
||||
function MyPromise(fun){ // 构造函数接收一个函数
|
||||
this.status = MyPromise.PENDING // 设置默认状态为待定
|
||||
try {
|
||||
fun.call(this, MyPromise.resolve.bind(this), MyPromise.reject.bind(this))
|
||||
} catch(err){
|
||||
// 如果MyPromise.prototype.then里面有err=>{}处理函数就传递给它
|
||||
this.status = MyPromise.REJECT
|
||||
this.result = err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Promise 状态常量
|
||||
MyPromise.PENDING = 0
|
||||
MyPromise.FULFILLED = 1
|
||||
MyPromise.REJECT = 2
|
||||
|
||||
|
||||
MyPromise.resolve = function(res) {
|
||||
if(this.status === MyPromise.REJECT) return // Promise 的状态一旦确定就不能修改
|
||||
this.status = MyPromise.FULFILLED
|
||||
this.result = res
|
||||
}
|
||||
|
||||
MyPromise.reject = function(err) {
|
||||
if(this.status === MyPromise.FULFILLED) return // Promise 的状态一旦确定就不能修改
|
||||
this.status = MyPromise.REJECT
|
||||
this.result = err
|
||||
}
|
||||
|
||||
MyPromise.prototype = {
|
||||
then: function(res, err){
|
||||
// Promise的.then要加入到任务队列,不能同步执行用setTimeout模拟
|
||||
var context = this // 保存的上下文
|
||||
setTimeout(function(){
|
||||
// 在.then中无论是onFulfilled的返回值还是onReject的返回值,都会交给下一个.then的onFulfilled处理,只有出现异常的时候才后交给下一个.then的onReject处理
|
||||
try{
|
||||
if(context.status === MyPromise.FULFILLED && res) context.result = res(context.result)
|
||||
if(context.status === MyPromise.REJECT && err) {
|
||||
context.result =err(context.result)
|
||||
context.status = MyPromise.FULFILLED
|
||||
}
|
||||
}catch(err){
|
||||
context.result = err
|
||||
context.status = MyPromise.REJECT
|
||||
}
|
||||
}, 0);
|
||||
return this
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user