• 异步解决方案


    什么是异步:

    当前一个任务被执行时,不会等待任务执行完成后就去执行下一个任务,等前一个任务执行完成后,将去执行其返回的回调函数,这是异步操作

    为什么要用异步:

    js是单线程的,因此必须等前一个任务完成后,后一个任务才会被执行。因此当执行一段耗时的程序时,会影响整个程序的执行,异步的方法就是为了解决这个问题。

    解决方案:

    1.回调函数callback:

    被作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数。如setTimeOut,ajax请求,readFile等。
    例:

    function greeting(name) {
      alert('Hello ' + name);
    }
    
    function processUserInput(callback) {
      var name = prompt('请输入你的名字。');
      callback(name);
    }
    
    processUserInput(greeting);
    
    优点:

    解决了异步的问题。

    缺点:

    回调地狱:多个回调函数嵌套的情况,使代码看起来很混乱,不易于维护。

    2.事件发布订阅

    当一个任务执行完成后,会发布一个事件,当这个事件有一个或多个‘订阅者’的时候,会接收到这个事件的发布,执行相应的任务,这种模式叫发布订阅模式。如node的events,dom的事件绑定
    例:

    document.body.addEventListener('click',function(){
      alert('订阅了');
    },false);
    document.body.click(); 
    
    优点:

    时间对象上的解耦。

    缺点:

    消耗内存,过度使用会使代码难以维护和理解

    3.Promise

    Promise是es6提出的异步编程的一种解决方案。
    Promise 对象有三种状态:

    • pending: 初始状态,既不是成功,也不是失败状态。
    • fulfilled: 意味着操作成功完成。
    • rejected: 意味着操作失败。
      promise的状态只能从pending变成fulfilled,和pending变成rejected,状态一旦改变,就不会再改变,且只有异步操作的结果才能改变promise的状态。
      例:
    let promise = new Promise(function (resolve, reject) {
        fs.readFile('./1.txt', 'utf8', function (err, data) {
            resolve(data)
        })
    })
    
    promise
        .then(function (data) {
            console.log(data)
        })
    
    优点:

    解决了回调地狱的问题,将异步操作以同步操作的流程表达出来。

    缺点:

    无法取消promise。如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。当执行多个Promise时,一堆then看起来也很不友好。

    4.Generator

    Generator是es6提出的另一种异步编程解决方案,需要在函数名之前加一个*号,函数内部使用yield语句。Generaotr函数会返回一个遍历器,可以进行遍历操作执行每个中断点yield。
    例:

    function * count() {
      yield 1
      yield 2
      return 3
    }
    var c = count()
    console.log(c.next()) // { value: 1, done: false }
    console.log(c.next()) // { value: 2, done: false }
    console.log(c.next()) // { value: 3, done: true }
    console.log(c.next()) // { value: undefined, done: true }
    
    优点:

    没有了Promise的一堆then(),异步操作更像同步操作,代码更加清晰。

    缺点:

    不能自动执行异步操作,需要写多个next()方法,需要配合使用Thunk函数和Co模块才能做到自动执行。

    5.async/await

    async是es2017引入的异步操作解决方案,可以理解为Generator的语法糖,async等同于Generator和co模块的封装,async 函数返回一个 Promise。
    例:

    async function read() {
     let readA = await readFile('data/a.txt')
     let readB = await readFile('data/b.txt')
     let readC = await readFile('data/c.txt')
    
     console.log(readA)
     console.log(readB)
     console.log(readC)
    }
    
    read()
    
    优点:

    内置执行器,比Generator操作更简单。async/await比*/yield语义更清晰。返回值是Promise对象,可以用then指定下一步操作。代码更整洁。可以捕获同步和异步的错误。

  • 相关阅读:
    ACMer第7天Falling Ants
    贪心初步-FatMouse' Trade
    贪心初步-A
    ACM集训第二天
    asp.net中遍历套用母版页的页面的控件
    a 标签中调用js的几种方法
    笔记
    html控件和web控件
    ASP.NET中GUID类
    (转)常见邮件服务器(接收服务器和发送邮件服务器)地址
  • 原文地址:https://www.cnblogs.com/smileyqp/p/12675349.html
Copyright © 2020-2023  润新知