美文网首页
JS异步编程——学习笔记

JS异步编程——学习笔记

作者: 我是一只小毛毛 | 来源:发表于2020-10-30 21:11 被阅读0次

    Javascript语言的执行环境是"单线程"(single thread),所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。

    为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。

    同步模式

    就是机械一行一行的执行代码直到代码结束,一旦出现问题就执行不下去了。

    异步模式

    就是执行到异步代码的时候会将这个代码内容暂时挂起,然后继续执行下面内容,当挂起的内容得到响应的时候,又返回来继续执行这个异步代码之后的内容。

    js常见的异步操作有:

    • setTimeout (setInterval)
    • AJAX
    • 事件绑定(如:.on,.bind,.listen,.addEventListener,.observe)
    • 观察者模式(例如:websocket中就有发布和订阅之类的操作)
    • promise 是一个异步操作,但是它是一个异步操作的解决方案,即保存着异步操作的结果,可以把异步函数以同步函数的形式写出来
    • async/await — 使用generator的语法糖,可以理解为是generator的一种改进
    • generator函数 — 使用promise的语法糖,可以理解为是promise的另一种拓展

    异步编程解决方案

    回调函数

    回调函数就是将一个函数当作另一个主函数的参数来使用的函数。

    function test2(){//回调函数
        console.log('执行了test2');
    }
    function test1(callback){ //(主函数)
        console.log('执行了test1');
       setTimeout(function () {
         callback();
       }, 1000);
    }
    // 执行
    test1(test2); 
    

    解读:回调函数是传统的一种异步编程解决方案,其原理就是将一个函数当作参数传递到另一个主函数中,当主函数执行完自身的内容之后,在运行传递进来的回调函数。这样就达成了类似异步的效果。

    缺点:一个任务只能有一个回调函数

    用法:回调函数在js中用的还是比较多的,例如:jsonp、ajax、一些常见的需要传递函数当参数来处理一些后续内容的操作

    回调函数分为异步回调和同步回调,其实区别就在于主函数中是否执行了异步操作而已

    promise

    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大,简单地说,Promise好比容器,里面存放着一些未来才会执行完毕(异步)的事件的结果,而这些结果一旦生成是无法改变的

    基本使用示例
    const promise = new Promise((resolve, reject) => {
        resolve(100)
        // reject(new Error('promise rejected'))  失败
    });
    
    promise.then(function (res) {
            return a();
        }).catch(function (e) {
            catchInfo(e);
        })
    
    console.log('end')
    

    Promise((resolve,reject)=>{}),当内部的异步操作完成后就执行resolve,如果出现异常就执行reject即可。resolve对应的是.then()、reject对应的是.catch();

    Promise的真正强大之处在于它的多重链式调用,可以避免层层嵌套回调。例如我们在ajax请求后,还要用它返回的结果再次请求,就可以使用Promise,利用then进行「链式回调」,将异步操作以同步操作的流程表示出来。

    链式调用示例
    let promise = new Promise((resolve, reject) => {
        resolve('999')
    })
    promise.then((value) => {
        console.log("成功11", value)
        return 100
    }).then((value) => {
        console.log("成功22", value)
        return 200
    }).then((value) => {
        console.log("成功33", value)
    })
    
    async-await

    async await也是异步编程的一种解决方案,他遵循的是Generator 函数的语法糖,他拥有内置执行器,不需要额外的调用直接会自动执行并输出结果,它返回的是一个Promise对象。

     async function test() {
        let aa = await aa();
        console.log(aa)
    }
    
    Promise和async/await比较

    Promise的出现解决了传统callback函数导致的“地域回调”问题,但它的语法导致了它向纵向发展行成了一个回调链,遇到复杂的业务场景,这样的语法显然也是不美观的。而async await代码看起来会简洁些,使得异步代码看起来像同步代码,await的本质是可以提供等同于”同步效果“的等待异步返回能力的语法糖,只有这一句代码执行完,才会执行下一句。

    async await与Promise一样,是非阻塞的。

    async await是基于Promise实现的,可以说是改良版的Promise,它不能用于普通的回调函数。

    相关文章

      网友评论

          本文标题:JS异步编程——学习笔记

          本文链接:https://www.haomeiwen.com/subject/hchjvktx.html