zoukankan      html  css  js  c++  java
  • 【JS】370- 总结异步编程的六种方式

    640?wx_fmt=png
    点击上方“前端自习课”关注,学习起来~

    作者:Aima

    https://segmentfault.com/a/1190000019188824

    众所周知 JavaScript 是 单线程工作,也就是只有一个脚本执行完成后才能执行下一个脚本,两个脚本不能同时执行,如果某个脚本耗时很长,后面的脚本都必须排队等着,会拖延整个程序的执行。那么如何让程序像人类一样可以多线程工作呢?以下为几种异步编程方式的总结,希望与君共勉。
    • 回调函数
    • 事件监听
    • 发布订阅模式
    • Promise
    • Generator (ES6)
    • async (ES7)

    异步编程传统的解决方案:回调函数事件监听
    初始示例:假设有两个函数, f1 和 f2,f1 是一个需要一定时间的函数。
    function f1() {	
        setTimeout(function(){	
            console.log('先执行 f1')	
        },1000)	
    }	
    function f2() {	
        console.log('再执行 f2')	
    }

    回调函数

    因为 f1 是一个需要一定时间的函数,所以可以将 f2 写成 f1 的 回调函数,将同步操作变成异步操作,f1 不会阻塞程序的运行,f2 也无需空空等待,例如 JQuery 的 ajax。
    回调函数的demo:
    function f1(f2){	
        setTimeout(function(){	
            console.log('先执行 f1')	
        },1000)	
        f2()	
    }	
    function f2() {	
        console.log('再执行 f2')	
    }
    效果如下:
    640?wx_fmt=png
    总结:回调函数易于实现、便于理解,但是多次回调会导致代码高度耦合

    事件监听

    脚本的执行不取决代码的顺序,而取决于某一个事件是否发生。
    事件监听的demo
    $(document).ready(function(){	
         console.log('DOM 已经 ready')	
    });

    发布订阅模式

    发布/订阅模式是利用一个消息中心,发布者发布一个消息给消息中心,订阅者从消息中心订阅该消息,。类似于 vue 的父子组件之间的传值。
    发布订阅模式的 demo
    //订阅done事件	
    $('#app').on('done',function(data){	
        console.log(data)	
    })	
    //发布事件	
    $('#app').trigger('done,'haha')

    Promise

    Promise 实际就是一个对象, 从它可以获得异步操作的消息,Promise 对象有三种状态,pending(进行中)、fulfilled(已成功)和rejected(已失败)。Promise 的状态一旦改变之后,就不会在发生任何变化,将回调函数变成了链式调用。
    Promise 封装异步请求demo
    export default function getMethods (url){	
        return new Promise(function(resolve, reject){	
            axios.get(url).then(res => {	
                resolve(res)	
            }).catch(err =>{	
                reject(err)	
            })	
        })	
    }	
    getMethods('/api/xxx').then(res => {	
        console.log(res)	
    }, err => {	
        console.log(err)	
    })

    Generator

    Generator 函数是一个状态机,封装了多个内部状态。执行 Generator 函数会返回一个遍历器对象,使用该对象的 next() 方法,可以遍历 Generator 函数内部的每一个状态,直到 return 语句。
    形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式, yield是暂停执行的标记。
    next() 方法遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。
    Generator 的 demo
    function *generatorDemo() {	
      yield 'hello';	
      yield  1 + 2;	
      return 'ok';	
    }	
    var demo = generatorDemo()	
    demo.next()   // { value: 'hello', done: false }	
    demo.next()   // { value: 3, done: false }	
    demo.next()   // { value: 'ok', done: ture }	
    demo.next()   // { value: undefined, done: ture }

    async

    async函数返回的是一个 Promise 对象,可以使用 then 方法添加回调函数,async 函数内部 return 语句返回的值,会成为 then 方法回调函数的参数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
    1.await命令后面返回的是 Promise 对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。
    async 的 demo1
    async function demo() {	
      try {	
        await new Promise(function (resolve, reject) {	
          // something	
        });	
      } catch (err) {	
        console.log(err);	
      }	
    }	
    demo().then(data => {	
        console.log(data)  //	
    })
    原创系列推荐



    4. 
    5. 
    6. 
    7. 

    640?wx_fmt=png

    回复“加群”与大佬们一起交流学习~

    640?wx_fmt=png
    点这,与大家一起分享本文吧~
    个人博客:http://www.pingan8787.com 微信公众号【前端自习课】和千万网友一起,每日清晨,享受一篇前端优秀文章。 目前已连续推送文章 600+ 天,愿每个人的初心都能一直坚持下去!
  • 相关阅读:
    $dp$模板
    字符串基础
    基础算法

    图论
    山中无甲子,寒尽不知年
    模板集合(持续更新)
    数学基础——同余
    9.19 考试总结
    1-5-17:菲波那契数列
  • 原文地址:https://www.cnblogs.com/pingan8787/p/11838070.html
Copyright © 2011-2022 走看看