JS 异步解决方案的发展历程解析

1.回调函数(callback)

setTimeout(() => {
    // callback 函数体
}, 1000)

缺点:回调地狱,不能用try catch 捕获错误,不能return

 try {
        setTimeout(() => {
            console.log(aa)
        }, 1000)
    } catch (error) {
        
}
//报错:Uncaught ReferenceError: aa is not defined

回调地狱的根本问题在于:

  • 缺乏顺序性: 回调地狱导致的调试困难,和大脑的思维方式不符
  • 嵌套函数存在耦合性,一旦有所改动,就会牵一发而动全身,即(控制反转)
  • 嵌套函数过多的多话,很难处理错误
function a(functionb(){
    c(function d(){
    
    })
})

如何解决回调地狱?(看下面的方法)

2.Promise(ES6)

  • Promise有三种状态:pending/reslove/reject 。pending就是未决,resolve可以理解为成功,reject可以理解为拒绝。
  • 同时Promise常用的三种方法 then 表示异步成功执行后的数据状态变为reslove catch 表示异步失败后执行的数据状态变为reject all表示把多个没有关系的Promise封装成一个Promise对象使用then返回一个数组数据。
function f(){
    let promise = new Promise((resolve, reject) => {
        //模拟异步
        setTimeout(()=>{
            resolve('prom')
        },1000)
        
    })
    return promise
}
function f1() {
 //返回一个Promise用于下一次调用then
     return f().then(data=>{
     // 返回的数据用于下一次then使用
         return data+'ise'
     })
 }
f1().then(data=>{
     console.log(data)
})
 console.log("hello word")	
 结果: hello word
promise

写成链式结构如下

new Promise((resolve, reject) => {
        //模拟异步
        setTimeout(()=>{
            resolve('prom')
        },1000)
        
    }).then(data=>{
        return data+'ise'
    }).then(data=>{
        console.log(data)
    })

缺点:无法取消 Promise ,错误需要通过回调函数来捕获

3.Generator(生成器,es6)

  • Generator(生成器)是一种有效利用内存的机制,一边循环一边计算生成数值的机制。通过配合Promise可以更加优雅的写异步代码
    特点 : 可以控制函数的执行
function *fetch() {
    yield ajax('XXX1', () => {})
    yield ajax('XXX2', () => {})
    yield ajax('XXX3', () => {})
}
let it = fetch()
let result1 = it.next()
let result2 = it.next()
let result3 = it.next()

缺点:生成器不是最完美的,它的语法让人难以理解

4.Async/await (异步等待, es7)

async、await 是异步的终极解决方案
优点:代码清晰,不用像 Promise 写一大堆 then 链,处理了回调地狱的问题
缺点:await 将异步代码改造成同步代码,如果多个异步操作没有依赖性而使用 await 会导致性能上的降低。
函数前面加async 表示该函数是一个异步函数 await 表示等待一个异步值的到来
eg1

async function test() {
  // 以下代码没有依赖性的话,完全可以使用 Promise.all 的方式
  // 如果有依赖性的话,其实就是解决回调地狱的例子了
  await fetch('XXX1')
  await fetch('XXX2')
  await fetch('XXX3')
}

异步函数可以更加方便的同Promise结合使用来书写同步代码风格的异步执行
eg2:

function f() {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{
            resolve("hello word")
        },1000)
    })
}
async function a(){
   var data = await f();
   return data;
}
a().then(data=>{
    console.log(data)
})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章