每天东看看西看看的,总结一下看到的东西吧
比较喜欢水文
1、讲讲async/await 其实也不知道具体怎么讲,看到最多的就是将异步执行变成同步执行,具体我也不了解,效果就是这样的
一、平时开发过程中遇到的
我要执行一个请求,然后就是等后端处理,这个处理时间,我也不清楚多久,我也不知道他处理啥,我就去干其余
的事情了,等他好了吧,那我等到通知了,我继续再处理发给你的请求的后续
之前的写法
function readFile (fileName, callback) {
setTimeout(() => {
console.log(fileName)
callback(null, `文件内容: ${fileName}`)
}, 1000);
}
readFile('1.txt', function (err, data1) {
if (err) {
console.log(err)
return
}
readFile('2.txt', function (err, data2) {
if (err) {
console.log(err)
return
}
console.log(data1, data2, '全部读取完成')
})
})
输出结果
问题 1、嵌套结构 -> 说是会有回调地狱的问题,我也没有遇到过,不敢说 2、错误处理比较难,一层一层的捕获 3、因为有setTimeout存在,执行顺序与代码顺序不一致,先把同步任务执行完成之后,再会去执行异步任务
promise链式调用
function readFilePromise (fileName) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`文件内容: ${fileName}`)
}, 1000);
})
}
readFilePromise('1.txt').then(data1 => {
return readFilePromise('2.txt')
}).then(data2 => {
console.log('全部读取完成')
})
总结一下: 1、扁平化调用,避免了嵌套 2、集中处理错误,catch 3、需要不停的累计写then
顺便说说promise相关的
promise 有三个状态 pending 等待中 fulfilled 成功 rejected 失败
状态是不可逆的
resolve,reject -- 只能放入一个参数,不能传递多个参数
promise.then(onFulfilled, onRejected)
onRejected 是可选的,失败是调用的
Promise.all 处理并行 Promise.resolve() Promise.reject() Promise.race() 简单来说是根据传入的iterable中第一个敲定的promise决定 Promise.allSettled() 并发处理,会获取所有的promise的结果
async/await调用
function readFilePromise(fileName) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`文件内容: ${fileName}`)
}, 1000);
})
}
async function readAllFiles() {
try {
const data1 = await readFilePromise('1.txt')
const data2 = await readFilePromise('2.txt')
console.log(data1, data2, '全部读取完成')
} catch (error) {
throw error
}
}
await readAllFiles()
再总结一下: 1、同步书写的体验啊,大部分人这么说的,但是想怎么写,还是跟随本心的 2、统一的处理 try catch 3、UI不卡顿、非阻塞执行
还是说说原理
async/await的背后原理是generator模拟同步
function readFilePromise(fileName) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`文件内容: ${fileName}`)
}, 1000);
})
}
function* readFileGenerator() {
const data1 = yield readFilePromise('1.txt')
const data2 = yield readFilePromise('2.txt')
return '完成'
}
function runGenerator(generator) {
const iterator = generator()
function next(value) {
const result = iterator.next(value)
console.log(result)
if (result.done) return
result.value.then(data => {
next(data)
})
}
next()
}
runGenerator(readFileGenerator)
1、yield 暂停函数,然后返回promise
2、promise完成之后,使用next(data)来恢复执行
3、runGenerator手动执行
然后说回为啥async/await 是非阻塞执行
首先是全局开始执行,然后是主线程执行,遇到await生成微任务塞入队列,等主线程执行之后,处理微任务(事件的循环机制)
总结一下: async/await 就是 Generator函数 + promise自动执行器 + 事件的循环调用机制; 另外一个说法就是 Generator的语法糖,通过状态机和Promise实现异步转同步 await暂停函数,返回promise-保存状态 通过primise完成后恢复执行,等待事件调用,代码顺序与逻辑顺序一致,但本质上还是异步