ps:只是针对看的某个课程做的一个简短笔记,方便后续自身复习,有时候逻辑或者板书并不是那么清晰,知识面可能也不全。有合适的机会后面会根据自己看的书籍、资料等完善和补充完善细节。
概述
本节概要
1.同步模式与异步模式
2.时间循环与消息队列
3.异步编程的几种方式
4.Promise异步方案、宏任务/微任务队列
5.Generator异步方案、Async/Await语法糖
单线程JavaScript单线程工作的原因:JS执行环境中负责执行代码的线程只有一个,js代码是运行在浏览器上,主要负责页面动态交互, DOM操作,为避免出现线程同步问题,所以单线程操作。
任务执行模式:同步模式、异步模式
回调函数
回调函数是所有异步编程的方案的根基
回调函数是由调用者定义,交给执行者执行的函数
Promise
解决回调地狱问题
const promise = new Promise((resolve, reject) => {
// resolve(50)
reject(new Error('error了喔'))
})
promise.then((data) => {
console.log(data)
}).catch((e)=>{
console.log('错误信息', e)
})
promise封装ajax
function ajax(url) {
return new Promise((resolve, reject)=>{
var xhr = new XMLHttpRequest()
xhr.open('get', url)
xhr.responseType = 'json'
xhr.onload = ()=>{
if(this.status === 200) {
resolve(this.message)
} else {
reject(new Error(this.statusText))
}
}
xhr.send()
})
}
ajax('/api/test.json').then((value)=>{
console.log(value)
}, (e)=>{
console.log('error', e)
})
unhandledRejection 捕获未手动捕获的异常
// 不推荐,应该在代码中明确捕获每一个可能的异常
window.addEventListener('unhandledRejection', e => {})
process.on('unhandledRejection', (reason, promise) => {
console.log(reason, promise)
// reason => Promise 失败原因,一般是个错误对象
// promise => 出现异常的Promise对象
})
promise静态方法
let p = new Promise((resolve, reject)=>{
resolve(67)
})
let p = Promise.resolve(3)
let p = Promise.reject('reject')
p.then((data)=>{
console.log(data+4)
}).catch(e=>{
console.log('error:', e)
})
// 如果传入的是一个对象,并且这个对象也有一个和promise一样的then方法,也能作为promise
// thenable方法。如果需要把第三方的promise对象转换成原生的promise对象可以以这种方式
Promise.resolve({
then: (onFulfilled, onRejected) =>{
onFulfilled(3)
}
})
.then((data)=>{
console.log(data+3)
})
promise并行执行多个异步任务
all等待所有的任务结束之后结束,返回数组;
race第一个任务结束则结束,返回第一个完成的任务的值;
finally方法用于指定不管Promise对象最后状态如何,都会执行的操作
let p1 = Promise.resolve(1)
let p2 = Promise.resolve(24)
let p3 = Promise.resolve(3535)
let allP =Promise.all([p1, p2, p3])
allP.then((e)=>{
console.log(e)
})
宏任务和微任务(消息队列和事件循环)
大部分异步调用的api都是作为宏任务执行的 ,promise的回调会作为微任务执行
微任务是为了提高整体的响应能力 eg:Promise & MutationObserver & process.nextTick
Generator异步方案
增强链式调用的可读性
Generate生成器处理异步任务 ES2015 co库
function * foo () {
console.log('start')
const res = yield 'foo'
console.log(res)
}
const generator = foo()
generator.next()
console.log(generator.next(123))
generator.throw(new Error('error'))
更优异步方案 异步调用更加扁平化
function * foo() {
console.log('start')
yield ajax('user.json')
yield ajax('user2.json')
// ...
}
const g = foo()
const res = g.next()
console.log(res)
处理逻辑,可使用递归优化
res.value.then((data => {
const res2 = g.next(data)
res2.value.then((data) => {
const res3 = g.next(data)
// ...
})
}))
递归优化版本,可复用
function co (generator) {
const g = generator
function handleResult (result) {
if (result.done) return // 生成器函数结束
result.value.then(data=> {
handleResult(g.next(data))
}, error => {
g.throw(error)
})
}
handleResult(g.next())
}
co(foo)
Async/Await 语法糖 最方便~
原创文章,作者:一苇,如若转载,请注明出处:https://wsppx.cn/886/%e7%bd%91%e7%bb%9c%e5%bc%80%e5%8f%91/%e5%89%8d%e7%ab%af/