异步无处不在:回调函数(二)

勾勾的前端世界

共 2050字,需浏览 5分钟

 ·

2021-01-13 14:14

(。・∀・)ノ゙嗨,我是你稳定更新、从不断更的勾勾。



上周五,我们聊了 JS 中的同步模式和异步模式。本篇,我们来唠唠回调函数


异步代码的执行流程如下:



通过上图,我们会看到,在整个代码的执行中,JS 本身的执行依然是单线程的,异步执行的最终结果,依然需要回到 JS 线程上进行处理。


在 JS 中,异步的结果回到 JS 主线程所采用的是 “ 回调函数 ” 的形式。


所谓的回调函数就是在 JS 主线程上声明一个函数,然后将函数作为参数传入异步调用线程,当异步执行结束后,调用这个函数,将结果以实参的形式传入函数的调用(也有可能不传参,但是函数调用一定会有)。


上篇的代码中 setTimeout 就是一个异步方法,传入的第一个参数就是回调函数,这个函数的执行就是消息队列中的 “回调”。


下面我们自己封装一个 ajax 请求,来进一步说明回调函数与异步的关系


Ajax 的异步请求封装

function myAjax(url,callback) {    var xhr = new XMLHttpRequest();    xhr.onreadystatechange = function () {        if (this.readyState == 4) {            if (this.status == 200) {                // 成功的回调                callback(null,this.responseText)            } else {                // 失败的回调                callback(new Error(),null);            }        }    }
xhr.open('get', url) xhr.send();}


上面的代码,封装了一个 myAjax 的函数,用于发送异步的 ajax 请求。


函数调用时,代码实际是按照同步模式执行的。当执行到 xhr.send() 时,就会开启异步的网络请求,向指定的 url 地址发送。从建立网络连接到断开网络连接的整个过程是异步线程在执行的。


换个说法就是 myAjax 函数执行到 xhr.send() 后,函数的调用执行就已经结束了。如果 myAjax 函数调用的后面有代码,则会继续执行,不会等待 ajax 的请求结果。


但是,myAjax 函数调用结束后,ajax 的网络请求却依然在进行着。


如果想要获取到 ajax 网络请求的结果,我们就需要在结果返回后,调用一个 JS 线程的函数,将结果以实参的形式传入:

myAjax('./d1.json',function(err,data){    console.log(data);})


回调函数让我们轻松处理异步的结果。但是,如果代码是异步执行的,而逻辑是同步的,就会出现 “回调地狱”,举个栗子:


代码 B 需要等待代码 A 执行结束才能执行,而代码 C 又需要等待代码 B,代码 D 又需要等待代码 C,而代码 A、B、C 都是异步执行的。


// 回调函数 回调地狱 myAjax('./d1.json',function(err,data){    console.log(data);    if(!err){        myAjax('./d2.json',function(err,data){            console.log(data);            if(!err){                myAjax('./d3.json',function(){                    console.log(data);                })            }        })    }})


没错,代码执行是异步的。但是异步的结果,是需要有强前后顺序的,著名的"回调地狱"就是这么诞生的。


相对来说,代码逻辑是固定的,但是编码体验要差很多,尤其在后期维护的时候,层级嵌套太深,让人头皮发麻。


如何让我们的代码不在地狱中受苦呢?

下篇告诉你(ง •_•)ง。


推荐阅读:

异步无处不在:同步模式和异步模式(一)

Redux 续集 | 如何搞定其中的异步操作?

技术人年度总结 | 2020,注定不平凡

2020 最后一篇技术文:可爱的乌咪 UmiJS

是我 Web 端配不上阿里了。

不可避免的问题:React 的路由如何抽离?

前端人因为 Vue3 的 Ref-sugar 提案打起来了!


点点“”和“在看”,保护头发,减少bug。

浏览 19
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报