JavaScript异步编程

news2025/2/26 20:11:02

回调地狱

        回调地狱是一种由于过度使用嵌套回调函数而导致的代码结构不清晰、难以理解和维护的问题。一个典型例子是嵌套多个回调函数,每个回调函数都作为另一个回调函数的参数。这样会导致各个部分之间高度耦合、程序结构混乱、流程难以追踪,每个任务只能指定一个回调函数,无法使用try catch捕获到回调函数中的异常,不能直接return。

手写Promise

        每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。Promise不仅能够捕获错误,而且也很好地解决了回调地狱的问题。它也存在一些缺点,比如无法取消Promise,错误需要通过回调函数捕获。

const promise = new Promise((resolve, reject) => {
   resolve('success')
   reject('err')
})
promise.then(value => {
  console.log('resolve', value)
}, reason => {
  console.log('reject', reason)
})
// 输出 resolve success

Promise的三种状态

  • Pending----Promise对象实例创建时候的初始状态
  • Fulfilled----可以理解为成功的状态
  • Rejected----可以理解为失败的状态

状态只能由Pending-->Fulfilled或者Pending-->Rejected,且一但发生改变就不可二次修改。

promise的链式调用

  • 每次调用返回的都是一个新的Promise实例(这就是then可用链式调用的原因)
  • 如果then中返回的是一个结果,会把这个结果传递下一次then中的成功回调
  • 如果then中出现异常,会走下一个then的失败回调
  • 在then中使用了return,那么return的值会被Promise.resolve()包装
  • then中可以不传递参数,如果不传递会透到下一个then中
  • catch会捕获到没有捕获的异常

细数异步场景与处理策略

  • 网络请求:例如使用fetch或XMLHttpRequest进行HTTP请求。

处理策略:使用.then()和.catch()处理Promise,或者使用async/await语法。

  • 定时器:如setTimeout和setInterval。

处理策略:使用回调函数或Promise封装定时器逻辑。

  • 文件读写:如使用FileReader读取文件内容。

处理策略:使用回调函数或Promise封装文件读写逻辑。

  • 事件监听:如点击事件、键盘事件等。

处理策略:在事件处理函数中使用异步代码,但需要注意事件循环和事件队列的处理。

  • Web Workers:用于在后台线程中执行耗时的计算任务,不阻塞主线程。

处理策略:使用postMessage和onmessage进行主线程和Worker线程之间的通信。

  • Promise链:多个异步操作需要依次执行。

处理策略:使用.then()串联多个Promise,或使用async/await语法。

  • 并行处理:多个异步操作可以同时进行,不需要等待其他操作完成。

处理策略:使用Promise.all()等待所有Promise完成,或使用async/await结合Promise.all()。

  • 错误处理:在异步操作中可能会遇到错误,需要妥善处理。

处理策略:使用.catch()捕获Promise中的错误,或使用try/catch捕获async/await中的错误。

从Promise到tj/co

        tj/co是一个基于JavaScript的协程库,它允许以同步的方式编写异步代码。这个库的核心思想是将异步操作转换为可以像同步代码一样顺序执行的流程,从而简化异步编程的复杂性。

        当使用co库时,可以编写一个生成器函数,并在其中使用yield关键字来暂停函数的执行,等待一个Promise的完成。当Promise完成时,生成器函数将恢复执行,并继续执行之后的代码。这个过程看起来就像是同步代码,但实际上它仍然是异步执行的。

const co = require('co');  
function* fetchData() { //生成器函数,使用yield来等待两个网络请求的完成  
  const user = yield fetch('/users/123').then(response => response.json());  
  const posts = yield fetch('/posts?user=' + user.id).then(response => response.json());  
  return posts;  
}  
co(fetchData).then(posts => {  
  console.log(posts);  
}).catch(err => {  
  console.error(err);  
});

从callback到promise

        最早期的异步编程主要依赖于回调函数(callback),但这种模式很快就暴露出了诸如回调地狱之类的问题,代码的可读性和维护性变得非常差。为了解决这个问题,Promise被引入作为一种更优雅的方式来处理异步操作。

async与await用法与原理详解

        一个函数如果加上async,那么该函数就会返回一个Promise。

        async关键字用于声明一个函数是异步的。这意味着该函数总是返回一个Promise对象。如果async函数返回一个值,这个值会被Promise对象解析为resolve值;如果async函数抛出异常,这个异常会被Promise对象解析为reject值。

        await关键字只能在async函数内部使用,它会暂停async函数的执行,等待Promise的完成或拒绝,并返回Promise的结果值。正常情况下,await命令后面是一个 Promise对象,返回该对象的结果。如果不是 Promise对象,就直接返回对应的值。

  • async/await只是Promise的语法糖,底层仍是基于Promise实现的,它不能用于普通的回调函数。
  • async/await与Promise一样,是非阻塞的。
  • async/await使得异步代码看起来像同步代码,这正是它的魔力所在。
  • 使用try/catch可以很容易地捕获async函数中的错误,这是处理Promise错误的一种更简洁的方式。
  • 可以在async函数中使用if语句、switch语句和for循环等,根据前一个异步操作的结果来决定是否执行下一个异步操作。

详解Promise A+规范

        Promise A+规范是Promise的官方规范,它详细定义了Promise的行为和特性。这个规范的目标是确保所有的Promise实现都具有一致的行为,从而使得开发者在使用Promise时不必担心不同库或环境之间的差异。

Promise A+规范主要包括以下几个部分:

  • 术语:规范首先定义了一些基本术语,如"promise"、"thenable"、"fulfilled"、"rejected"和"resolution procedure"等。
  • 对象状态:一个Promise对象必须处于以下状态之一:pending(挂起)、fulfilled(实现)或rejected(拒绝)。只有异步操作的结果才能改变这个状态,任何其他操作都无法改变这个状态。
  • then方法:Promise必须提供一个then方法,该方法接受两个参数:onFulfilled和onRejected,它们都是可选的,都是函数。这两个函数都将在promise被相应状态改变后异步执行。then方法返回一个新的promise,这个新的Promise的状态和值取决于onFulfilled或onRejected函数的返回值。
  • Promises/A+规范中的then方法的行为:规范详细描述了then方法的执行过程,包括如何处理onFulfilled和onRejected函数的返回值,如何处理异常,以及如何处理promise链等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1473653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaScript 漫游】【023】Event 对象总结

文章简介 本篇文章为【JavaScript 漫游】专栏的第 022 篇文章,记录了 JavaScript 中 Event 对象的相关知识点。 Event 对象概述 事件发生以后,会产生一个事件对象,作为参数传给监听函数。浏览器原生提供一个 Event 对象,所有的…

设计模式(六)代理模式

相关文章设计模式系列 1.代理模式简介 代理模式介绍 代理模式也叫委托模式,是结构型设计模式的一种。在现实生活中我们用到类似代理模式的场景有很多,比如代购、代理上网、打官司等。 定义 为其他对象提供一种代理以控制这个对象的访问。 代理模式…

支付宝小程序智能客服开发文档

语雀参考文档 https://www.yuque.com/em8gt4/qw1tt1/xgz1ol 自定义客服组件&#xff08;仅专业模式支持&#xff09; <contact-button tnt-inst-id"企业编码" scene"聊天窗编码" size"咨询按钮大小" color"咨询按钮颜色" icon&qu…

DBeaver一段时间不使用,就会自动断开连接,需要刷新数据库或者断开重连解决方案 DB2

DBeaver一段时间不使用&#xff0c;就会自动断开连接&#xff0c;需要刷新数据库或者断开重连解决方案 DB2

【Flink】Flink 中的时间和窗口之窗口(Window)

1. 窗口的概念 Flink是一种流式计算引擎&#xff0c;主要是来处理无界数据流&#xff0c;数据流的数据是一直都有的&#xff0c;等待流结束输入数据获取所有的流数据在做聚合计算是不可能的。为了更方便高效的处理无界流&#xff0c;一种方式就是把无限的流数据切割成有限的数…

【hashset】【hash查找元素O(1 )时间复杂度】Leetcode 128. 最长连续序列

【hashset】【hash查找元素O&#xff08;1 &#xff09;时间复杂度】Leetcode 128. 最长连续序列 解法1 hashmap解法2 不满足题设 排序遍历 ---------------&#x1f388;&#x1f388;题目链接&#x1f388;&#x1f388;------------------- 解法1 hashmap 核心思想 利用了ha…

Vue3的8大生命周期

查看本专栏目录 关于作者 还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#x…

Vue.js+SpringBoot开发快递管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快递区域模块2.4 快递货架模块2.5 快递档案模块 三、界面展示3.1 登录注册3.2 快递类型3.3 快递区域3.4 快递货架3.5 快递档案3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 …

windows 连接 Ubuntu 失败 -- samba服务

1. windows10连接ubuntu的时候&#xff0c;提示不允许一个用户使用一个以上用户名与服务器或共享资源的多重连接&#xff0c;中断与此服务器或共享资源的所有连接&#xff0c;然后再试一次 2. 换一台同事的电脑却又可以连上&#xff0c;我之前一直能用的&#xff0c;隔一段时间…

【 C++ 】bitset位图的模拟实现

位图概念 曾经有这样一个面试题&#xff0c;如果给你40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中。【腾讯】方法如下&#xff1a; 遍历&#xff0c;时间复杂度O(N)。排序(O(NlogN))&#xff0c;利用二…

文献速递:深度学习--深度学习方法用于帕金森病的脑电图诊断

文献速递&#xff1a;深度学习–深度学习方法用于帕金森病的脑电图诊断 01 文献速递介绍 人类大脑在出生时含有最多的神经细胞&#xff0c;也称为神经元。这些神经细胞无法像我们身体的其他细胞那样自我修复。随着年龄的增长&#xff0c;神经元逐渐死亡&#xff0c;因此变得…

袁庭新ES系列12节 | Elasticsearch高级查询操作

前言 上篇文章讲了关于Elasticsearch的基本查询操作。接下来袁老师为大家带来Elasticsearch高级查询部分相关的内容。Elasticsearch是基于JSON提供完整的查询DSL&#xff08;Domain Specific Language&#xff1a;领域特定语言&#xff09;来定义查询。因此&#xff0c;我们有…

Python实现自动检测设备连通性并发送告警到企业微信

背景&#xff1a;门禁机器使用的WiFi连接&#xff0c;因为某些原因会不定期自动断开连接&#xff0c;需要人工及时干预&#xff0c;以免影响门禁数据同步&#xff0c;故写此脚本&#xff0c;定时检测门禁网络联通性。 #首次使用要安装tcping模块 pip install tcpingfrom tcpin…

幻兽帕鲁服务器哪家便宜?阿里云腾讯云京东云华为云对比

幻兽帕鲁服务器哪家便宜&#xff1f;阿里云腾讯云京东云华为云对比&#xff0c;阿里云更便宜&#xff0c;26元1个月。游戏服务器租用多少钱一年&#xff1f;1个月游戏服务器费用多少&#xff1f;阿里云游戏服务器26元1个月、腾讯云游戏服务器32元&#xff0c;华为云26元&#x…

Android WebView访问网页+自动播放视频+自动全屏+切换横屏

一、引言 近期&#xff0c;我发现电视家、火星直播等在线看电视直播的软件都已倒闭&#xff0c;而我奶奶也再无法通过这些平台看电视了。她已六十多岁&#xff0c;快七十岁啦。这些平台的倒下对我来说其实没有多大的影响&#xff0c;但是对于文化不多的她而言&#xff0c;生活中…

常见需求:CSS 实现弧形卡片的 3 种方式

公众号&#xff1a;程序员白特&#xff0c;欢迎一起交流学习~ 原文作者&#xff1a;前端侦探 在平时开发中&#xff0c;有时候会碰到下面这种“弧形”样式&#xff0c;主要分为“内凹”和“外凸”两种类型&#xff0c;如下 该如何实现呢&#xff1f;或者想一下&#xff0c;有哪…

用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细,万字详述)

目录 一、打包前置知识 1.1 什么是 exe 可执行文件&#xff1f; 1.2 为什么要将 Python 程序打包为 exe 可执行文件&#xff1f; 1.3 为什么 Python 程序不能直接运行呢&#xff1f; 1.4 我们用什么来打包 Python 文件呢&#xff1f; 1.5 打包有哪几种分类呢&#xff1f…

Spring-Cloud-Gateway集成Sentinel限流

1&#xff09;gateway添加sentinel相关依赖 <spring-cloud.version>2021.0.1</spring-cloud.version> <spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version><dependencies><!--gateway--><dependency><gro…

多模态表征—CLIP及中文版Chinese-CLIP:理论讲解、代码微调与论文阅读

我之前一直在使用CLIP/Chinese-CLIP&#xff0c;但并未进行过系统的疏导。这次正好可以详细解释一下。相比于CLIP模型&#xff0c;Chinese-CLIP更适合我们的应用和微调&#xff0c;因为原始的CLIP模型只支持英文&#xff0c;对于我们的中文应用来说不够友好。Chinese-CLIP很好地…

为什么要智慧公厕?智慧公厕是做什么的

在现代城市信息化建设进程中&#xff0c;公共卫生设施的建设与管理一直备受关注。而随着科技的迅速发展&#xff0c;智慧公厕作为一种新型的信息化公共设施&#xff0c;正逐渐走进人们的视野。本文以智慧智慧源头厂家广州中期科技有限公司&#xff0c;大量精品案例现场实景&…