回调函数的那些事

回调函数

这只是一个称呼,表达的含义是 将函数A作为函数B的参数,并且函数A在函数B内进行调用。

这可以用来解决异步。因为异步的时候我们不能一直等待,因此需要一个函数来在异步操作执行完了以后,继续接下来的顺序操作。

举例:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<p>点击按钮,3 秒后会弹出 "Hello"。</p>
<button onclick="myFunction()">点我</button>

<script>
var myVar;

function myFunction() {
    myVar = setTimeout(alertFunc, 3000);
}

function alertFunc() {
  alert("Hello!");
}
</script>

</body>
</html>

在这个例子中,点击按钮“点我”,会触发myFunction函数,函数中有一个异步函数,settimeout,其中传递了自定义的回调函数alertFunc。

解释一下: settimeout是一个封装好的函数,给我们暴露一个参数接口,传递自定义的回调函数。

同时,这个回调函数在调用的时候可能要进行一定传参。

同时对回调函数传参有两种方式:

  1. 将回调函数的参数作为与回调函数同等级的参数进行传递

    img

  2. 回调函数的参数在调用回调函数内部创建

    img

相信以上描述已经让大家明白了回调函数的使用。那么,接下来,让我们讨论一下令人诟病已久的回调地狱和它的解决方法吧。

首先,文字解释一下回调地狱,即:多次连续异步操作造成不停写入回调函数,而导致代码的可读性和维护性变差。

举个例子:

var fs = require('fs');

fs.readFile('./views/index.html',  (err, data) => {
    if (err) {
        throw err
    }
    fs.readFile('./views/main.html', (err, data) => {
        if (err) {
            throw err
        }
        fs.readFile('./views/update.html', (err, data) => {
            if (err) {
                throw err
            }
            console.log(data.toString());
        })   
        console.log(data.toString());
    })
    console.log(data.toString());
})

为了保证顺序,依次执行三个异步操作。每个一步操作都有一个回调函数。

如果我不进行说明,这个代码的可读性是不是很差呢?

那么,有没有什么办法能够改进这种形式呢?

既然回调函数是在异步操作执行完再进行调用,那我们能不能按照这个逻辑,把代码写成“顺序执行的呢?1、2、3”这样。

ok,那接下来我们引入,promise的概念:

promise代表一个异步操作;通过promise进行异步操作,异步操作完成之后,通过resolve函数,promise从pending变成fulfilled状态,并抵达then方法。如果操作失败,通过reject函数,promise从pending变成rejected。

其中涉及到promise原理部分,推荐几个阅读材料:

  1. 这个带着我了解了promise的底层思想。resolve和reject作为一个函数是怎么改变promise状态的。

    then又是怎么进行处理的。

    https://www.jianshu.com/p/43de678e918a

    这是一个英文的promise的介绍,感觉可以一看。

    http://www.mattgreer.org/articles/promises-in-wicked-detail/

    https://www.promisejs.org/

那么async和await又是用来做什么的呢?

他也是用来解决异步编程的,大家称之为“最终解决方案”

单纯的写回调函数,很容易形成回调地狱。因此我们提出了promise,通过then和catch来处理成功或失败之后的结果。 但是通过then去解决回调链,依旧有点难度。能否用同步代码的形式去写异步的操作?

这就是async、await大杀器。

通过async关键字声明函数内部存在异步操作。通过await声明异步操作。

其成熟的解释在:

https://segmentfault.com/a/1190000007535316

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值