从回调地狱到async/await:JavaScript异步执行的进化之路!

在JavaScript中,代码的异步执行是为了处理那些需要等待一段时间才能返回结果的操作,比如网络请求、文件读取等。这样的操作会阻塞程序的执行,降低用户体验。为了解决这个问题,JavaScript提供了多种异步处理方案:回调函数、Promise和async/await。

回调函数

回调函数是最早被广泛使用的异步处理方式。通过将一个函数作为参数传递给异步操作,在操作完成后调用该函数来处理结果。

javascript 复制代码
// 要求先打印Hello,然后再打印World
function a() {
// 模拟异步操作
    setTimeout(() => {
        console.log("Hello");
        b()
    }, 1000);
}

function b() {
    console.log("World");
}
a() // 输出Hello World

回调函数可以实现简单的异步操作,但当有多个异步操作需要依次执行时,就会出现回调地狱的问题。

Promise

Promise是ES6引入的一种更优雅的异步处理方式。它可以链式调用,避免了回调地狱的问题。

javascript 复制代码
// 要求先打印Hello,然后再打印World
function a() {
    return new Promise((resolve, reject) => {
        // 模拟异步操作
        setTimeout(() => {
            console.log("Hello");
            resolve();
        }, 1000);
    })
}

function b() {
    console.log("World");
}
a().then(() => {
    b();
}) // 输出 Hello World

Promise对象有三种状态:pending(进行中)、resolved(已完成)和rejected(已失败)。通过调用resolve()和reject()方法,可以改变Promise的状态。

.then()方法用于注册回调函数,当Promise的状态变为resolved时,将调用.then()中的回调函数。可以在.then()后面继续调用.then(),实现多个异步操作的链式调用

需要注意的是:

  • resolve(参数) 这个参数会被then中的回调函数接收
  • then方法会默认返回一个Promise对象,所以then2(多个调用时)可以接在then后面,但当then当中有人为返回一个Promise对象时,then2就接在人为返回的那个Promise对象后面

async/await

async/await是ES7引入的异步处理方式,使用起来更加简洁和直观。它基于Promise

  • async 相当于 return new Promise((resolve, reject) => {})
  • await 相当于 .then

通过使用async函数和await关键字提供一种更类似同步代码的写法。

javascript 复制代码
// 要求先打印Hello,然后再打印World
function a() {
    return new Promise((resolve, reject) => {
     // 模拟异步操作
        setTimeout(() => {
            console.log("Hello");
            resolve();
        }, 1000);
    })    
}

function b() {
    console.log("World");
}

(async function c() {
    await a();
    b();
})() // 输出 Hello World

在async函数内部,可以使用await关键字暂停代码的执行,等待一个Promise对象的结果。当await后面的表达式(通常是一个Promise对象)完成后,async函数将继续执行后面的代码。

使用async/await可以使异步代码看起来像同步代码,提高代码的可读性和维护性。

综上所述,JavaScript提供了回调函数、Promise和async/await等多种解决方案来处理异步执行,以提升代码质量和用户体验。

相关推荐
樊小肆31 分钟前
# 你还在等DeepSeek官方 agent Harness‌? 来试试 DeepSeeker-Code吧
前端·人工智能·后端
樊小肆32 分钟前
2568 万 token 才花 2 块 2:聊聊 DeepSeeker-Code 怎么吃满上下文缓存
前端·人工智能·后端
JarvanMo42 分钟前
Flutter 3.47: material/cupertino终于解耦了
前端
郭邯1 小时前
一次「字符洁癖」引发的思考:我用 AI 写了个全角半角转换工具
前端
想要成为糕糕手1 小时前
🚀 在浏览器里跑 DeepSeek-R1?WebGPU 端侧推理实战(五)—— 中断、重置、缓存与流式生成
前端·react.js·llm
GuWenyue1 小时前
后端接口又双叒没写好?3 步搭建前端 Mock,从此告别"傻等后端"
前端·mocha
海兰1 小时前
【数据采集】开源的 Web 数据采集与处理Firecrawl(一)
前端·开源
vivo互联网技术1 小时前
从一键检测到 AI 修复:我们如何把无障碍检查做进研发流程
前端·人工智能
liuxiaocheng1 小时前
聊聊 Vercel AI SDK 的流式协议:前后端到底是怎么"边想边说"的
前端·后端
胡萝卜术1 小时前
在浏览器中跑 DeepSeek-R1:WebGPU 推理全流程深度解析
前端·javascript·面试