”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > JavaScript 中的异步编程:回调、Promise、Async/Await

JavaScript 中的异步编程:回调、Promise、Async/Await

发布于2024-07-31
浏览:892

Asynchronous Programming in JavaScript: Callbacks vs Promises vs Async/Await

异步编程是 JavaScript 的一个关键方面,它允许开发人员在不阻塞主线程的情况下执行长时间的网络请求、文件操作和其他耗时的任务。这可确保应用程序保持响应灵敏且用户友好。 JavaScript 提供了三种主要方式来处理异步操作:回调、Promises 和 Async/Await。在本文中,我们将深入研究这些方法,通过详细的示例探索它们的语法、用法和差异。

目录

  1. 异步编程简介
  2. 回调
    • 语法和示例
    • 的优点和缺点
  3. 承诺
    • 语法和示例
    • 链接承诺
    • 的优点和缺点
  4. 异步/等待
    • 语法和示例
    • 错误处理
    • 的优点和缺点
  5. 比较和最佳实践
  6. 结论

异步编程简介

在 JavaScript 中,需要时间才能完成的操作(例如从服务器获取数据、读取文件或执行计算)可以异步处理。这意味着在等待操作完成时,JavaScript 引擎可以继续执行其他任务。这对于在 Web 应用程序中创建高效、流畅的用户体验至关重要。

回调

语法和示例

回调是 JavaScript 中最早处理异步操作的方法之一。回调只是一个作为参数传递给另一个函数的函数,该函数将在异步操作完成后执行。

function fetchData(callback) {
    setTimeout(() => {
        callback("Data fetched!");
    }, 1000);
}

function displayData(data) {
    console.log(data);
}

fetchData(displayData);

在上面的例子中,fetchData使用setTimeout模拟异步操作。 1 秒后,它调用 displayData 函数,将获取的数据作为参数传递。

的优点和缺点

优点:

  • 简单明了的小任务。
  • 提供了一种在异步操作完成后执行代码的方法。

缺点:

  • 多个异步操作嵌套时会导致“回调地狱”,导致代码难以阅读和维护。
  • 错误处理很麻烦,因为需要在每个回调中管理错误。

承诺

语法和示例

ES6 (ECMAScript 2015) 中引入了 Promise 来解决与回调相关的问题。 Promise 代表尚未完成但预计将来会完成的操作。它可以处于三种状态之一:待处理、已完成或已拒绝。

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("Data fetched!");
        }, 1000);
    });
}

fetchData()
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error("Error:", error);
    });

在此示例中,fetchData 返回一个 Promise,该 Promise 解析为“Data fetched!” 1秒后。 then 方法用于处理解析后的值,catch 用于处理任何错误。

链接承诺

Promise 可以链接起来按顺序执行一系列异步操作。

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("Data fetched!");
        }, 1000);
    });
}

function processData(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(`${data} Processed!`);
        }, 1000);
    });
}

fetchData()
    .then(data => {
        console.log(data);
        return processData(data);
    })
    .then(processedData => {
        console.log(processedData);
    })
    .catch(error => {
        console.error("Error:", error);
    });

本例中,在fetchData之后调用processData,并使用then按顺序处理结果。

的优点和缺点

优点:

  • 通过允许异步操作的链接来避免回调地狱。
  • 通过 catch 提供内置错误处理。
  • 提高代码可读性和可维护性。

缺点:

  • 通过多个嵌套的 then 调用仍然会变得复杂。
  • 链中的错误处理可能很重要。

异步/等待

语法和示例

Async/Await 在 ES2017 中引入,提供了一种更可读、更简洁的方式来使用 Promises 编写异步代码。 async 关键字用于定义异步函数,await 关键字用于暂停执行,直到 Promise 得到解析。

async function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("Data fetched!");
        }, 1000);
    });
}

async function displayData() {
    const data = await fetchData();
    console.log(data);
}

displayData();

在此示例中,displayData 是一个异步函数,它在记录数据之前等待 fetchData 完成。

错误处理

可以使用 try/catch 块来完成 Async/Await 的错误处理。

async function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject("Failed to fetch data!");
        }, 1000);
    });
}

async function displayData() {
    try {
        const data = await fetchData();
        console.log(data);
    } catch (error) {
        console.error("Error:", error);
    }
}

displayData();

这里,如果 fetchData 失败,错误将被 catch 块捕获并记录。

的优点和缺点

优点:

  • 简化异步代码,使其看起来更像同步代码。
  • 增强代码可读性和可维护性。
  • 使用 try/catch 块简化错误处理。

缺点:

  • 需要了解 Promise,因为 Async/Await 是建立在 Promise 之上的。
  • 仍然相对较新,因此某些环境可能不完全支持它。

比较和最佳实践

比较

  • 回调:适合简单的单级异步任务,但在复杂场景下可能会导致回调地狱。
  • Promises:提高可读性和可管理性,允许异步操作的链接。使用 catch 内置错误处理。
  • Async/Await:提供最具可读性和可维护性的异步代码编写方式。简化错误处理并且看起来像同步代码。

最佳实践

  • 对于大多数需要处理异步操作的场景,使用 Async/Await。它提供了最佳的可读性和简单性。
  • 当您需要按顺序执行多个异步操作或使用返回 Promises 的库时,请使用 Promises
  • 避免回调除非使用遗留代码或处理非常简单的异步任务。

结论

JavaScript 中的异步编程对于构建响应迅速且高效的应用程序至关重要。了解回调、Promises 和 Async/Await 之间的差异使开发人员能够为其特定用例选择正确的工具。虽然回调是处理异步操作的最简单形式,但它们可能会导致代码混乱。 Promise 提供了一种更加结构化的方法,但 Async/Await 提供了最优雅和可读的解决方案。通过遵循最佳实践并了解这些工具,开发人员可以编写干净、可维护且高效的异步代码。

版本声明 本文转载于:https://dev.to/itsshaikhaj/asynchronous-programming-in-javascript-callbacks-vs-promises-vs-asyncawait-690?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 解决MySQL插入Emoji时出现的\\"字符串值错误\\"异常
    解决MySQL插入Emoji时出现的\\"字符串值错误\\"异常
    Resolving Incorrect String Value Exception When Inserting EmojiWhen attempting to insert a string containing emoji characters into a MySQL database us...
    编程 发布于2025-05-06
  • 图片在Chrome中为何仍有边框?`border: none;`无效解决方案
    图片在Chrome中为何仍有边框?`border: none;`无效解决方案
    在chrome 中删除一个频繁的问题时,在与Chrome and IE9中的图像一起工作时,遇到了一个频繁的问题。和“边境:无;”在CSS中。要解决此问题,请考虑以下方法: Chrome具有忽略“ border:none; none;”的已知错误,风格。要解决此问题,请使用以下CSS ID块创建带...
    编程 发布于2025-05-06
  • PHP与C++函数重载处理的区别
    PHP与C++函数重载处理的区别
    作为经验丰富的C开发人员脱离谜题,您可能会遇到功能超载的概念。这个概念虽然在C中普遍,但在PHP中构成了独特的挑战。让我们深入研究PHP功能过载的复杂性,并探索其提供的可能性。在PHP中理解php的方法在PHP中,函数超载的概念(如C等语言)不存在。函数签名仅由其名称定义,而与他们的参数列表无关。...
    编程 发布于2025-05-06
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-05-06
  • 如何实时捕获和流媒体以进行聊天机器人命令执行?
    如何实时捕获和流媒体以进行聊天机器人命令执行?
    在开发能够执行命令的chatbots的领域中,实时从命令执行实时捕获Stdout,一个常见的需求是能够检索和显示标准输出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    编程 发布于2025-05-06
  • HTML格式标签
    HTML格式标签
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    编程 发布于2025-05-06
  • 人脸检测失败原因及解决方案:Error -215
    人脸检测失败原因及解决方案:Error -215
    错误处理:解决“ error:((-215)!empty()in Function Multultiscale中的“ openCV 要解决此问题,必须确保提供给HAAR CASCADE XML文件的路径有效。在提供的代码片段中,级联分类器装有硬编码路径,这可能对您的系统不准确。相反,OPENCV提...
    编程 发布于2025-05-06
  • 为什么在我的Linux服务器上安装Archive_Zip后,我找不到“ class \” class \'ziparchive \'错误?
    为什么在我的Linux服务器上安装Archive_Zip后,我找不到“ class \” class \'ziparchive \'错误?
    class'ziparchive'在Linux Server上安装Archive_zip时找不到错误 commant in lin ins in cland ins in lin.11 on a lin.1 in a lin.11错误:致命错误:在... cass中找不到类z...
    编程 发布于2025-05-06
  • 您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    在javascript console 中显示颜色是可以使用chrome的控制台显示彩色文本,例如红色的redors,for for for for错误消息?回答是的,可以使用CSS将颜色添加到Chrome和Firefox中的控制台显示的消息(版本31或更高版本)中。要实现这一目标,请使用以下模...
    编程 发布于2025-05-06
  • 如何在其容器中为DIV创建平滑的左右CSS动画?
    如何在其容器中为DIV创建平滑的左右CSS动画?
    通用CSS动画,用于左右运动 ,我们将探索创建一个通用的CSS动画,以向左和右移动DIV,从而到达其容器的边缘。该动画可以应用于具有绝对定位的任何div,无论其未知长度如何。问题:使用左直接导致瞬时消失 更加流畅的解决方案:混合转换和左 [并实现平稳的,线性的运动,我们介绍了线性的转换。这...
    编程 发布于2025-05-06
  • Android如何向PHP服务器发送POST数据?
    Android如何向PHP服务器发送POST数据?
    在android apache httpclient(已弃用) httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(“ http://www.yoursite.com/script.p...
    编程 发布于2025-05-06
  • 如何解决由于Android的内容安全策略而拒绝加载脚本... \”错误?
    如何解决由于Android的内容安全策略而拒绝加载脚本... \”错误?
    Unveiling the Mystery: Content Security Policy Directive ErrorsEncountering the enigmatic error "Refused to load the script..." when deployi...
    编程 发布于2025-05-06
  • Python读取CSV文件UnicodeDecodeError终极解决方法
    Python读取CSV文件UnicodeDecodeError终极解决方法
    在试图使用已内置的CSV模块读取Python中时,CSV文件中的Unicode Decode Decode Decode Decode decode Error读取,您可能会遇到错误的错误:无法解码字节 在位置2-3中:截断\ uxxxxxxxx逃脱当CSV文件包含特殊字符或Unicode的路径逃...
    编程 发布于2025-05-06
  • 对象拟合:IE和Edge中的封面失败,如何修复?
    对象拟合:IE和Edge中的封面失败,如何修复?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    编程 发布于2025-05-06
  • 如何使用Python有效地以相反顺序读取大型文件?
    如何使用Python有效地以相反顺序读取大型文件?
    在python 反向行读取器生成器 == ord('\ n'): 缓冲区=缓冲区[:-1] 剩余_size- = buf_size lines = buffer.split('\ n'....
    编程 发布于2025-05-06

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3