js回调的心酸历程

作者: an祭 | 来源:发表于2017-10-26 16:20 被阅读0次

项目代码

demo准备的啰嗦了,如果你同我一样是个急性子,可以直接忽略

捂脸

需求

demo中src文件里有a、b、c三个json文件,需求是我们需要依次请求它们,并且打印它们的值。

发展史

  • ES5 - 金字塔
  • ES6 - 链式
  • ES6 - 暂停
  • ES7 - 同步

ES5 - 金字塔

首先我们来到ES5的时代,为完成以上的需求写下如下的代码:

  $.ajax('./src/a.json').done((a)=>{

        console.log(a.data) // 打印a文件

        $.ajax('./src/a.json').done((b)=>{

              console.log(b.data)  // 打印b文件

              $.ajax('./src/a.json').done((c)=>{
                       console.log(c.data)  // 打印c文件
              })
        })
  })
  

嗯,也不错啊,一层套着一层,也算清晰明了了。如果当我们的需要改成100个文件的依次获取呢?此时,如果还这样写的话,那欢迎你来到回调地狱

如果我们嵌套很多的代码,像金字塔一样的堆叠起来,不仅仅让代码显得更加难看、臃肿,也让项目变得越来越不好维护。

ES6 - 链式

我们来到了ES6的时代,这个时代的有个产物叫做promise

通过promise我们可以将代码链式的调用�改成��如下的代码

function request(url){
    return new Promise((resolve, reject)=>{
        $.ajax(url).done((data)=>{
            resolve(data)
        }).fail((err)=>{
            reject(err)
        })
    })
}

request('./src/a.json').then((a)=>{
    console.log(a)
    return request('./src/b.json')
}).then((b)=>{
    console.log(b)
    return request('./src/c.json')
}).thne((c)=>{
    console.log(c)
})

相比金字塔式嵌套的代码,此时的代码更加的简洁,也更容易维护,但是也只不过是将嵌套改成了上下链接调用。

ES6 - 暂停

Generator 函数是 ES6 提供的一种异步编程解决方案,可以理解成内部有很多状态的状态机。

generator函数与普通函数区别:

  • 定义的时候多了个*
  • 函数内部使用yield来定义不同的状态
  • 调用的时候,需要将函数赋值给某个变量,每个变量之间的状态互不影响
  • 使用next()函数调用下一个状态
function request(url){
    $.ajax(url).done((data)=>{
        generator.next(data)
    })
}


function* generatorFn(){
    let a = yield request('./src/a.json')
    console.log(a)
    let b = yield request('./src/b.json')
    console.log(b)
    let c = yield request('./src/c.json')
    console.log(c)
}

var generator = generatorFn()

generator.next()

以上代码定义了generatorFn函数并赋值给generator,在定义request函数的时候,当请求到数据的时候,调用generator的next方法。

ES7 async/await

万众瞩目,神器登场 async/await

先上代码:

(async () => {
    let a = await $.ajax('./src/a.json')
    console.log(a)
    let b = await $.ajax('./src/b.json')
    console.log(b)
    let c = await $.ajax('./src/c.json')
    console.log(c)
})

async函数是generator函数的语法糖,只是将*变成了async,yield改成了await,但是代码却精简了这么多,它们直接的区别有以下几点:

  • async函数不用手动去调用next() 函数
  • async函数返回值是promise,generator函数返回的是Iterator

async函数可以看成一个包含多个异步操作的promise的对象,await就是then的语法糖。

四种方式中最精简的方式。使用async处理回调函数,代码会异常的清新,我们写起来也会很爽很舒服。

为什么会有这种感觉呢?

因为它是最符合我们写代码的习惯,用同步的写法去解决异步的代码。

参考文档:

相关文章

  • js回调的心酸历程

    项目代码 demo准备的啰嗦了,如果你同我一样是个急性子,可以直接忽略 需求 demo中src文件里有a、b、c三...

  • web前端面试3

    1 JS异步解决方案的发展历程以及优缺点 1,回调函数(无法捕获错误(使用try catch) 不能return)...

  • 你不知道的JS(中卷)第七章

    第七章 回调 回调是js异步的基本单元。随着js越来越成熟,对于异步编程的发展,回调已经不够用了。回调表达异步流的...

  • node.js(六)

    Node.js 回调函数Node.js 异步编程的直接体现就是回调。异步编程依托于回调来实现,但不能说使用了回调后...

  • 2020-02-23

    Node.js回调函数 Node.js异步编程的直接体现就是回调 异步编程依托于回调来实现,但不能说使用了回调后程...

  • weex学习第二节

    weex实现js调native方法和native回调js方法 学习weex时发现js调native方法和nativ...

  • 代码格式测试

    这是常见的js回调

  • 将CallBack改写成Promise

    CallBack回调函数是js的特色之一, 但CallBack回调方法, 非常容易造成回调地狱(callback ...

  • 异步

    JS 异步解决方案的发展历程以及优缺点。 1、回调函数(callback)优点:解决了同步的问题(只要有一个任务耗...

  • Js中的回调

    Js中的callback机制,即回调.JS中用到回调的几种情况:1.动态加载(外部)js的时候,在加载完成之后进行...

网友评论

    本文标题:js回调的心酸历程

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