promise
- 参数为一个函数,这个函数的参数为 resolve, reject 执行promise参数函数内容后将正确结果用resolve返回 错误结果用reject返回 每个新的promise对象实例最初都是pending状态,当他执行了resolve后就将状态变成了fulfilled 当执行reject后状态就变成了rejected,这个状态只能正向改变,不可逆也不可变,不论是resolve还是reject都执行一次,且执行他们后这个参数函数停止执行后面的代码
let eg = new Promise((resolve, reject) => {
if(Math.random()>0.5) {
resolve('大于0.5')
} else {
reject('不大于0.5')
}
// 后面的代码不会执行了
})
- 正确的结果由then 方法接受,错误的异常又catch接受
eg.then(res => {}).catch((err)=> {})
手动实现一个promise
const PENDING = 'PENDING'
const RESOLVED = 'fulfilled'
const REJECTED = 'REJECTED'
function _Promise(fn) {
this.status = PENDING
this.value = ''
this.err = ''
this.resolveStack = []
this.rejectStack = []
this.resolve = function (value) {
this.status = RESOLVED
this.value = value
this.resolveStack.forEach(item => {
item()
});
}
this.reject = function (err) {
this.status = REJECTED
this.reason = err
this.rejectStack.forEach(item => {
item()
});
}
try {
fn(resolve,reject)
} catch {
reject(err)
}
})
.then .all
Promise.protortype._then = function (onFulfilled, onRejected) {
if (this.status == PENDING) {
resolveStack.push(onFulfilled)
rejectStack.push(onRejected)
} else if (this.status == RESOLVED) {
resolveStack.push(onFulfilled)
} else if (this.status = REJECTED) {
rejectStack.push(onRejected)
}
}
Promise.prototype._all = function(promiseArr) {
return new Promise((resolve,reject) => {
let results = []
let count = 0
promiseArr.forEach(item => {
item.then(res => {
results.push(res)
count++
}).catch(err => {
reject(err)
})
})
if(count == promiseArr.length) {
resolve(results)
}
})
}
async
async 函数 会返回一个promise 如果返回是一个值则用resolve包裹起来
- async 附魔过的函数 会把return的结果包裹在promise中
async function getSomething() {
return "something";
}
const v1 = getSomething(); // 一个promise
async function testAsync() {
return Promise.resolve("hello async");
}
const v2 = testAsync();
- await 只能使用在async函数内部,用于接收promise的返回值,如果promise返回错误 await将抛出错误,通过try/catch捕获
function p1() {
return new Promise((res,rej) => {
console.log('p1')
res('p1 resolved')
})
}
async function op1(){
const a = await p1()
console.log(a)
return a
}
事件循环机制
- 同步任务遇到就执行,异步任务将放入异步队列栈中,当同步执行全部完成后,开始执行异步栈中的异步任务
- 异步任务内部也存在异步任务,依旧放入队列中,
- 异步任务分为宏任务和微任务,如果任务中的宏任务完成,就判断它是否存在微任务,如果有就执行微任务。上述任务全部完成后,再进行下一轮任务
- 宏任务:script/setTimeout/setInterval/setImmediate/ I/O / UI Rendering
- 微任务:process.nextTick()/Promise
for(let macroTask of macroTaskQueue) {
handMacroTask()
for(let microTask of microTaskQueue) {
handMicroTask()
}
}
console.log('scriptstart')
setTimeout(() => {
console.log('setTimeout1');
Promise.resolve().then(() => {
console.log('promise1')
})
}, 0)
new Promise(resolve => {
console.log('promise2');
setTimeout(() => {
console.log('setTimeout2');
resolve();
}, 0)
})
Promise.resolve().then(() => {
console.log('promise3');
setTimeout(() => {
console.log('setTimeout3')
},0)
}).then(() => console.log('promise4'))
console.log('scriptend');
scriptstart promise2 scriptend promise3 promise4 setTimeout1 promise1 setTimeout2 setTimeout3