走走看看 2025-8-5

46 阅读2分钟

每天东看看西看看的,总结一下看到的东西吧

比较喜欢水文

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, '全部读取完成')
            })
        })

输出结果

image.png

问题 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完成后恢复执行,等待事件调用,代码顺序与逻辑顺序一致,但本质上还是异步