【前端面经】JS-异步解决方案

这篇具有很好参考价值的文章主要介绍了【前端面经】JS-异步解决方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

同步和异步

众所周知, JavaScript是一门单线程的语言, 单线程就意味着同一时间只能执行一个任务, 当前任务执行结束, 才会执行下一个任务. 这种模式的好处就是执行环境比较单纯, 但坏处也很明显, 一旦有某个任务卡住了, 就会导致整个程序阻塞. 为了解决这个问题, JS将任务的执行模式分成了同步(Synchronous)异步(Asynchronous)两种.

更详细的同步异步的执行模式可以参考事件循环

下面我们就来讲讲JS异步编程的几种解决方案.

1.回调函数

回调函数是异步编程的最基本的方法, 它通常作为一个参数传递给另一个函数, 并且在父函数执行完成后执行回调函数

例如:

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

function parent(a, callback) {
    console.log(a);
    typeof callback === 'function' ? callback() : return
}

parent('a', logB)

在上面的例子中, 在parent函数中, 如果callback参数传入的是一个函数, 那么在输出形参a之后就会执行callback函数, 上述例子中logB就是作为回调函数传入parent中并执行

在实际开发过程中, 回调函数的使用场景还是很多的, 例如常见的数组遍历方法forEach, 其第一个参数就是回调函数

let arr = [1, 2, 3]
arr.forEach((item) => {
    console.log(item);
})

回调函数的优点是简单易懂, 但其实一旦嵌套起来很不利于代码的维护和可读性. 而且各个部分之间高度耦合, 流程会比较混乱. 最经典就是回调地狱(callback hell).
在实际开发过程中, 经常能遇到一些业务需要先发送一个请求获取数据后, 再根据这个请求的返回结果再发送第二个请求, 第三个请求可能又需要第二个请求的返回结果作为参数, 如此层层嵌套就称之为回调地狱, 这样的代码就很难维护.

ajax('url1', (res1) => {
    console.log(res1)
    ajax('url2+res1', (res2) => {
        console.log(res2)
        ajax('url3 + res2', (res) => {
            console.log(res3)
            ...
        })
    })
})

优点: 简单易懂
缺点: 多层回调函数嵌套时容易混乱, 不利于代码维护和可读性, 容易写出回调地狱

事件监听

这种方式, 异步任务的执行不取决于代码的执行顺序, 而取决于某个事件是否发生.

element.addEventListener('click', ()=> {
    console.log('click')
})

上面这个例子的含义是, 当element被点击时, 就会输出click

  • 优点: 比较容易理解, 并且可以绑定多个事件, 每个事件可以指定多个回调函数, 可以比较好的去耦合, 有利于实现模块化.
  • 缺点: 整个程序变成了事件驱动型, 运行流程很不清晰, 比较难看出主流程, 代码可读性低

Promise

Promise是一种处理异步代码(并且不会陷入回调地狱)的方式

Promise代表一个异步操作, 其有三种状态pending(进行中)fulfilled(已完成)rejected(已失败), 一个Promise对象必然处于这三种状态之一

  • pending: 初始状态, 既没有完成, 也没有被拒绝
  • fulfilled: 操作成功完成
  • rejected: 操作失败

Promise被调用后, 它会以pending开始, 代码会继续往下执行, 而Promise仍处于pending状态, 直到执行完成为止, 最终会以fulfilledrejected结束, 并对应的传给回调函数–then或者catch.
优点: 不仅可以解决回调地狱问题, 而且能够捕获错误并进行处理
缺点: 无法取消Promise

Generator

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同,Generator 最大的特点就是可以控制函数的执行。

语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。
Generator 函数除了状态机,还是一个遍历器对象生成函数。
可暂停函数, yield可暂停,next方法可启动,每次返回的是yield后的表达式结果。
yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。

async/await

本质上async和await是Promise的语法糖, 它可以使得异步代码看起来像同步代码一样

更加详细的Promise可以参考: Promise

总结

  1. JS 异步编程进化史: callbackpromisegeneratorasync/await
  2. async/await 函数的实现,就是将 Generator 函数和自动执行器,包装在一个函数里。
  3. async/await可以说是异步终极解决方案了。

(1) async/await函数相对于Promise, 优势体现在:

  • 处理 then 的调用链,能够更清晰准确的写出代码
  • 并且也能优雅地解决回调地狱问题。
    当然async/await函数也存在一些缺点:
  • 因为 await 将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了 await 会导致性能上的降低,代码没有依赖性的话,完全可以使用 Promise.all 的方式。

(2) async/await函数对 Generator 函数的改进,体现在以下三点:

  1. 内置执行器。

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

  2. 更广的适用性。

    co 函数库约定,yield 命令后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面,可以跟 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。

  3. 更好的语义。

    async 和 await,比起星号和 yield,语义更清楚了。async 表示函数里有异步操作,await 表示紧跟在后面的表达式需要等待结果。文章来源地址https://www.toymoban.com/news/detail-433980.html

到了这里,关于【前端面经】JS-异步解决方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • @Async异步线程:Spring 自带的异步解决方案

            在项目应用中,使用MQ异步调用来实现系统性能优化,完成服务间数据同步是常用的技术手段。如果是在同一台服务器内部,不涉及到分布式系统,单纯的想实现部分业务的异步执行,这里介绍一个更简单的异步方法调用。         对于异步方法调用,从Spring3 开

    2023年04月24日
    浏览(48)
  • JavaScript 异步编程解决方案-中篇

    1.Promise 构造函数:new Promise(executor) Promise() 只能通过 new 运算符来构造。如果尝试在没有使用 new 的情况下调用它,会抛出 TypeError 异常。 1.executor 执行器函数:(resolve,reject)={} 2.resolve 函数:内部定义成功时候调用values={} 3.reject 函数:内部定义失败时候调用error={} 备注:e

    2024年01月23日
    浏览(37)
  • JavaScript 异步编程解决方案-上篇

    1、JavaScript 异步编程 1、传统的方案 :JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理 场景:fs 文件操作 数据库操作 AJAX 定时器 eg: 1、setTimeout 函数

    2024年02月01日
    浏览(30)
  • Go异步任务解决方案 Asynq

    今天为大家介绍一个Go处理异步任务的解决方案:Asynq,是一个 Go 库,用于排队任务并与 worker 异步处理它们。它由Redis提供支持,旨在实现可扩展且易于上手。 Asynq 是一个 Go 库,用于对任务进行排队并与工作人员异步处理它们。 Asynq 工作原理的高级概述: 客户端将任务放入

    2024年01月17日
    浏览(32)
  • 【go】异步任务解决方案Asynq实战

    Asynq 是一个 Go 库,一个高效的分布式任务队列。 Asynq 工作原理: 客户端(生产者)将任务放入队列 服务器(消费者)从队列中拉出任务并为每个任务启动一个工作 goroutine 多个工作人员同时处理任务 git库:https://github.com/hibiken/asynq Asynq 使用 Redis 作为消息代理。client 和 se

    2024年02月10日
    浏览(32)
  • JavaScript 异步解决方案 Promise 全解析(转载)

    Promise 是一个 JS 的异步编程解决方案,解决了传统异步编程回调地狱的问题。 从语义上来说: Promise 是一个向外部传达异步编程操作消息的对象。 JS里一个promise可以有以下几种基本状态: nothing happened yet \\\"locked in\\\" to another promise fulfilled rejected 其中{1,2}为 pending ,{3,4}为 settl

    2024年02月08日
    浏览(45)
  • Redux异步解决方案 1. Redux-Thunk中间件

    简单介绍一下 thunk ,这是一个中间件,是解决 redux 异步问题产生的。我们都知道,在使用 redux 的时候,通过 dispatch 一个 action 发生到 reducer 然后传递给 store 修改状态 一系列都是同步的,那如果说我 dispatch 一个 action 这个 action 帮我请求一下接口数据,你发现接口请求是异步

    2024年02月09日
    浏览(35)
  • Microsoft ToDo无法同步的解决方案

    问题:在开DAILI的情况下,Microsoft to-do、邮件、日历等UWP均无法正常同步。 此文中解释了原因 link UWP 是微软在 Windows 10 中引入的新概念,由于所有 UWP 应用均运行在被称为 App Container 的虚拟沙箱环境中,其安全性及纯净度远胜于传统的 EXE 应用。但 App Container 机制同时也阻止

    2024年02月05日
    浏览(36)
  • 主从同步的延迟问题、原因及解决方案

    主从同步的延迟问题、原因及解决方案 MySQL的主从同步在实际使用过程中会有从库延迟的问题,那么为什么会有这种问题呢? 如何避免这种问题呢? 情况一: 从服务器配置过低导致延迟 这类延迟场景的出现往往是主节点拥有较大规格的配置,而只读节点却购买了一个最小规格的

    2024年02月16日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包