js-review/js/js异步.js

79 lines
3.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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);
// })
// 执行顺序不是12345而是13452这是由于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
}
}