JavaScript异步机制与方案

文章介绍了JavaScript的单线程特性以及由此引发的同步与异步执行的概念。异步编程包括回调函数、事件监听、Promise、Generator和async/await。回调函数易造成回调地狱,Promise改善了这一问题,Generator允许函数暂停执行,而async/await提供了更简洁的异步处理方式,使得异步代码接近同步风格。
摘要由CSDN通过智能技术生成

JavaScript异步机制与方案

前言:Javascript语言的执行环境是"单线程"。也就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务。

这种模式虽然实现起来比较简单,执行环境相对单纯,但是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。

为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步和异步。主要介绍异步编程几种办法,并通过比较,得到最佳异步编程的解决方案。

一、同步与异步

1.同步:同步就是后一个任务等待前一个任务执行完毕后,再执行,执行顺序和任务的排列顺序一致。

举个例子:按照排队的顺序,依次打饭,只有前面一个人打完饭后,才轮到后面一个人。

2.异步:异步是非阻塞的,异步逻辑与主逻辑相互独立,主逻辑不需要等待异步逻辑完成,而是可以立刻继续下去。 

主逻辑指的是程序中执行同步任务的代码部分,该部分代码会按照代码顺序执行,直到全部执行完毕或者遇到阻塞(例如 I/O 操作)时会暂停执行等待操作完成。

异步逻辑指的是程序中执行异步任务的代码部分,异步逻辑与主逻辑相互独立,不会阻塞主逻辑的执行,异步任务执行完毕后,触发回调函数来通知主逻辑执行后续处理。异步任务可以是网络请求、文件读取、计时器等操作,这些操作都可能需要一定时间才能完成,因此需要异步进行执行。

举个例子:有同学忘记带饭卡了,怎么办?如果一直等着饭卡拿来,那是不是很花时间,后面同学就不能打饭了!所以呢,我让出来,让后面的人先打饭,等我的饭卡到了,我再打饭

二、异步编程

1.回调:回调简单地理解为一个函数作为参数传递给另一个函数

用回调函数来获取异步数据

优点:简单,容易理解。

缺点:代码不优雅,可读性差,不易维护,耦合度高,层层嵌套造成回调地狱。

回调地狱:代码难以维护,我们要获取异步程序的数据,不能用return拿数据,用回调函数拿,就要控制顺序,就要用嵌套,嵌套的多了,代码难以维护。

2.事件监听:

采用事件驱动模式,通过监听事件的触发来执行相应的操作。这种方式可以避免阻塞主线程,提高程序的响应速度和效率。

任务的执行不取决代码的顺序,而取决于某一个事件是否发生。

比如onload加载图片,addEvenListener监听点击事件

优点: 比较容易理解,可以绑定多个事件,每一个事件可以指定多个回调函数,而且可以去耦合,有利于实现模块化。

缺点: 整个程序都要变成事件驱动型,运行流程会变得不清晰。

3.promise

Promise 优点和缺点

优点:Promise以同步的方式编写异步代码,避免了回调函数层层嵌套,可读性更强。链式操作,可以在then中继续写Promise对象并return,然后继续调用then进行回调操作。

缺点:Promise对象一旦创建就会立即执行,不能中途取消。如果没有设置回调函数,Promise 会在内部抛出错误,不会向外流。

4.Generator

概念

Generator函数是es6的,作用是可以将函数执行时可以进行暂停,而普通函数是一直执行到 return,同样也是异步的一种解决方案

定义 Generator 函数

定义函数时通过 function* 进行区分为 Generator 函数

函数内部可以通过 yield 进行暂停 定义普通函数

调用函数

函数直接调用即可,但是函数不会执行,此时只是得到了一个 Generator 对象,需要调用 Generator 对象的 next 方法逐步执行。

yield 向外传递数据

generator 函数可通过 yield 传递数据到函数外,函数外通过调用 next 接收

 

向函数内传递数据

第一次 next 传递参数无效,第一次的 next 的参数由函数调用传递

下一次的 next 传递的参数,由上一次的 yield 暂停后重新执行进行返回

处理异步

配合 promise

改成递归方式调用

 但是此时没有考虑 co 的返回值为 promise, 所以 co 方法还需返回 promise,一旦返回 promise 又要考虑成功和失败的结果,此时直接使用 co 库。利用 co 库自动执行

利用 co 库自动执行

用于 Generator 函数的自动执行

优点:优雅的流程控制方法,允许函数被中断地执行。

缺点:Generator函数的执行必须依赖executor(执行器),对于只做异步处理还是不太方便。

5.async+await:

async函数对generator函数的改进:

(1)内置执行器:generator函数的执行必须靠执行器,所以才有了co函数库,而async函数自带执行器,也就是说,async函数的执行,与普通函数一模一样,只要一行。

(2)更好的语义。Async和await,比起*和yield,语义更清楚。Async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

async/await的目的为了简化使用基于promise的API时所需的语法。async/await 的行为就好像搭配使用了生成器(generator)和promise。

优点:内置执行器,语义更好,适用性更广。

缺点:误用 await 可能会导致性能问题,因为 await 会阻塞代码。

Async/Await 是一种比较新的异步编程技术,它使异步代码看起来像同步代码,更加直观和易于理解。Async/Await 的实现原理是 Generator 函数和 Promise,它通过同步的方式实现异步。使用 Async/Await 可以避免回调地狱和 Promise 层层嵌套的问题。Async/Await 通常用于处理多个异步操作的情况,这样的代码看起来非常简单和直观。

js中异步的应用场景

定时任务:setTimeout、setInterval

网络请求:ajax请求、动态创建img标签的加载

事件监听器:addEventListener

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值