logo

第六章:异步编程

作者
Modified on
Reading time
3 分钟阅读:..评论:..

1. 回调函数

在 JavaScript 中,异步编程是处理时间消耗任务(如网络请求、文件读取等)的核心技术之一。回调函数是处理异步操作的最基本方式。

什么是回调函数

回调函数是作为参数传递给另一个函数的函数,当那个函数完成其任务后会调用这个回调函数。此模式常用于处理异步操作。以下是一个基本示例:

function loadScript(src, callback) { let script = document.createElement("script"); script.src = src; script.onload = () => callback(null, script); script.onerror = () => callback(new Error(`Script load error for ${src}`)); document.head.append(script); } // 使用回调函数加载脚本 loadScript("path/to/script.js", (error, script) => { if (error) { console.error(error); } else { console.log(`${script.src} has been loaded successfully.`); } });

使用回调函数处理异步操作

回调函数非常有用,但当多个异步操作需要串行执行时,回调函数会导致回调地狱问题。以下是多个异步操作的示例:

loadScript("script1.js", (error, script1) => { if (error) { console.error(error); } else { loadScript("script2.js", (error, script2) => { if (error) { console.error(error); } else { loadScript("script3.js", (error, script3) => { if (error) { console.error(error); } else { console.log("All scripts loaded successfully"); } }); } }); } });

2. Promise

Promise 的基本概念

Promise 是异步编程的一种解决方案,它比传统的回调函数和事件更优雅。Promise 可以使异步代码看起来像同步代码,避免了回调地狱。

创建与使用 Promise

Promise 构造函数接受一个回调函数,该回调函数有两个参数:resolvereject。调用 resolve 表示成功,调用 reject 表示失败。例如:

let promise = new Promise((resolve, reject) => { // 异步操作代码 setTimeout(() => { resolve("Success!"); }, 1000); }); // 使用 .then 和 .catch 处理 Promise promise .then((message) => { console.log(message); // 'Success!' }) .catch((error) => { console.error(error); });

Promise 链与错误处理

Promise 支持链式调用,通过 .then() 可以将多个异步操作串联起来。每个 .then() 都返回一个新的 Promise,因此可以继续调用 .then().catch() 进行错误处理。例如:

loadScript("script1.js") .then((script1) => { console.log(`${script1.src} loaded`); return loadScript("script2.js"); }) .then((script2) => { console.log(`${script2.src} loaded`); return loadScript("script3.js"); }) .then((script3) => { console.log("All scripts loaded successfully"); }) .catch((error) => { console.error(`Error: ${error.message}`); });

3. async/await

async/await 的基本概念

asyncawait 是基于 Promise 的语法糖,使得异步代码看起来像同步代码,从而简化异步操作。async 函数总是返回一个 Promise,await 只能在 async 函数中使用。

使用 async/await 简化异步代码

下面是一个使用 async/await 简化后的异步操作示例:

async function loadAllScripts() { try { let script1 = await loadScript("script1.js"); console.log(`${script1.src} loaded`); let script2 = await loadScript("script2.js"); console.log(`${script2.src} loaded`); let script3 = await loadScript("script3.js"); console.log("All scripts loaded successfully"); } catch (error) { console.error(`Error: ${error.message}`); } } loadAllScripts();

错误处理与同步风格

async/await 中,可以使用 try...catch 来处理错误,这种方式类似于同步代码中的错误处理:

async function loadScriptWithErrorHandling(src) { try { let script = await loadScript(src); console.log(`${script.src} loaded successfully`); return script; } catch (error) { console.error(`Error loading script: ${error.message}`); } } loadScriptWithErrorHandling("script1.js");

通过 async/await,我们可以编写出更加清晰、易读的异步代码,大大提高了代码的可维护性。

接下来,我们将进入更加实战和高级的部分,了解如何操作 DOM 和处理浏览器事件。