软件教程 2025年08月6日
0 收藏 0 点赞 925 浏览 2207 个字
摘要 :

文章目录 一、异步编程中的难题与现有方案 (一)promise解决异步的方式及问题 (二)generator处理异步的情况 二、async和await的优势 三、async的实现原理 四、asyn……




  • 一、异步编程中的难题与现有方案
    • (一)promise解决异步的方式及问题
    • (二)generator处理异步的情况
  • 二、async和await的优势
  • 三、async的实现原理
  • 四、async和await的不足

JavaScript异步编程中我们已经有了promise来处理异步操作,可为何官方还要引入asyncawait呢?这背后其实有着深层次的考量,接下来就让我们一探究竟。

一、异步编程中的难题与现有方案

在实际开发中,发接口请求是常见的操作。有时,我们需要保证接口请求的顺序,然而各个接口的耗时又不尽相同,这就需要将异步操作“捋”成同步的效果。

(一)promise解决异步的方式及问题

以模拟接口请求为例,下面这段代码展示了使用promise解决异步的方式:

function request (num) { 
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(num * 10)
        }, 1000)
    })
}

// const res1 = request(1)
// const res2 = request(res1)

request(1).then(res1 => {
    console.log(res1);
    request(res1).then(res2 => {
        console.log(res2);
    })
})

上述代码实现了两次接口请求,且第二次请求依赖第一次请求返回的结果。但这种链式调用的方式,代码看起来较为繁琐,不够优雅。

(二)generator处理异步的情况

再来看generator处理异步的方式,以下是模拟三次请求的代码:

function* gen() { // generator处理异步
    const num1 = yield request(1)
    const num2 = yield request(num1)
    const num3 = yield request(num2)
    return num3
}

let g = gen()
const next1 = g.next()
next1.value.then(res1 => {
    console.log(res1);
    const next2 = g.next(res1)
    next2.value.then(res2 => {
        console.log(res2);
        const next3 = g.next(res2)
        next3.value.then(res3 => {
            console.log(res3);
        })
    })
})

可以看到,generator处理异步时,代码同样不美观,调用过程也比较复杂。

二、async和await的优势

asyncawait的出现,很好地解决了上述问题。下面通过代码来看看它们是如何工作的:

async function fn() {
    const res1 = await request(1) // await会把promise中的resolve值提取出来
    const res2 = await request(res1)
    console.log(res2);
}
fn()

相较于promise的链式调用和generator复杂的调用方式,asyncawait的代码更加简洁直观,将异步操作写得如同同步操作一般,极大地提高了代码的可读性。

三、async的实现原理

asyncawait的实现是基于promisegenerator的。其中,async关键字会让函数默认返回一个promise对象。如果一个函数接收的参数是函数体,或者返回一个函数体,那么这个函数就是高阶函数async相关的函数就属于这类。

async的核心其实是generator,只不过在使用generator时,需要手动不断调用next函数,而async通过递归实现了generatornext函数自动化执行。以下是async的核心实现代码(类似co模块的源码loop函数):

function generatorToAsync(generatorFn) {
    // 生成generator对象
    const gen = generatorFn()
    return function () {
        return new Promise((resolve, reject) => {
            function loop (key, arg) {
                let res = null
                // 执行generator的next方法或throw方法
                res = gen[key](arg)
                const { value, done } = res
                // 如果generator执行结束
                if (done) {
                    return resolve(value)
                } else {
                    // 将value转为promise,处理异步结果
                    Promise.resolve(value).then(res => { 
                        loop(\'next\', value)
                    })
                }
            }
            // 开始执行
            loop(\'next\')
        })
    }
}

在这段代码中,generatorToAsync函数接收一个generatorFn,返回一个新函数。新函数返回一个Promise,内部通过loop函数递归调用generatornext方法,直到donetrue,结束递归并返回最终结果。

四、async和await的不足

asyncawait虽然强大,但也并非完美。它没有内置的错误捕获机制,所以在使用时,需要开发者手动使用try...catch来捕获可能出现的错误。

asyncawait通过递归自动化执行generatornext函数,优化了异步操作的代码编写方式。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/6891.html

管理员

相关推荐
2025-08-06

文章目录 一、Promise基础回顾 二、Promise 与 axios 结合使用场景及方法 (一)直接返回 axios …

269
2025-08-06

文章目录 一、模块初始化时的内部机制 二、常见导出写法的差异分析 (一)写法一:module.exports…

107
2025-08-06

文章目录 一、ResizeObserver详解 (一)ResizeObserver是什么 (二)ResizeObserver的基本用法 …

683
2025-08-06

文章目录 一、前期准备工作 (一)下载相关文件 (二)安装必要工具 二、处理扣子空间生成的文件…

338
2025-08-06

文章目录 一、官方文档 二、自动解包的数据类型 ref对象:无需.value即可访问 reactive对象:保持…

371
2025-08-06

文章目录 一、Hooks的工作原理 二、在if语句中使用Hook会出什么岔子? 三、React官方的Hook使用规…

843
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号