回调函数 -----【全球化下的产业分工】

大家好,今天我们要聊的是这回调函数。那么什么是回调函数?常见的回调函数的应用有哪些?回调函数存在的意义又是什么?它又有哪几种存在的形式?怎么正确而又合理地利用回调函数以及应用时我们又应该注意哪些问题呢?接下来Edward小编就和大家一起来分享一下......

 

 

1. 定义

A callback is a function that is passed as an argument to another function and is executed after its parent function has completed。

(回调函数就是一个函数,将这个函数作为参数传到另一个函数里面,当那个父函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调。)

 下面是百度词条给出的定义:

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

 

上面都是官方给出的一些定义,其实回调函数通俗地讲,就是把一个函数B以参数的形式传到另外一个函数A中,让A函数在一定的(适当的)时机用到B函数,从而让B函数实现其自身的作用。
举个简单的例子:
 
【故事背景】:
19世纪后期到20世纪中叶,美国取代了英国,成为世界工业强国,经济的全球化也意味着产业分布的日趋明显。发达国家掌握高精尖技术的同时,把资源/劳动力密集型的产业转移到了发展中国家。A国负责整车,而B国 /E国的轴承,C国 /F国生产的轮胎,D国的方向盘......最终运往A国,而A国整车完毕之后则销往全球市场。
 
[ 分析 ]:在这个过程中,A国的整车流水线除了安装轴承,轮胎,方向盘......之类的部件以外,先需要安装其他的零件,等到需要用到BCDEF国零件的时候,再回过头来调用一下这些零部件。至于最终组装完成后的某个汽车的轮胎,A国并不关心用的是C国的还是F国的,只要是同一个型号和质量即可,而同样BCDEF国在生产这些零件的时候,也并不确定这些零部件是卖给A国,Q国,Z国,还是最终积压成了库存。
 
 
回调方法 是任何一个被以该回调方法为其第一个参数 的 其它方法 调用 的方法。很多时候,回调是一个当某些事件发生时被调用的方法。

控制台打印结果如下:

 

2. 同步回调  vs  异步回调:

 现在我们把函数 Fn A 中调用 Fn B 的地方换成 setTimeout 异步操作,

 控制台打印结果如下:

 

 

3. 为什么要有异步回调?

    --->异步回调: 因为js是单线程的, 但是有很多情况的执行步骤( ajax请求远程数据, IO等) 是非常耗时的,
    如果一直单线程的堵塞下去会导致程序的等待时间过长页面失去响应, 进而影响用户体验

 

 控制台打印结果如下:

 javascript是一门单线程的非阻塞的脚本语言。

这是由其最初的用途来决定的:与浏览器交互。单线程意味着,javascript代码在执行的任何时候,都只有一个主线程来处理所有的任务。

而非阻塞则是当代码需要进行一项异步任务(无法立刻返回结果,需要花一定时间才能返回的任务,如I/O事件)的时候,主线程会挂起(pending)这个任务,然后在异步任务返回结果的时候再根据一定规则去执行相应的回调。

 

3. 意义:

因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。简而言之,回调函数就是允许用户把需要调用的函数的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。

其实,我们经常能够用到回调函数。当我们在平时用各种插件的时候,第三方插件库会给我们写好插件大体的轮廓,而我们则把配置项传给插件,这个给插件配置的过程就是回调的过程。又比如在fetch/ axios 请求成功时,我们需要传入一个函数,这也是回调的过程......

【值得注意的是】:

1.回调函数是异步编程最基本的方法,
   其优点是简单、容易理解和部署,
   缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。
 
2.回调并不一定就是异步。他们自己并没有直接关系。
 
3. 异步回调和同步回调最大的区别就是:
    异步回调添加了回调需要满足的条件, 也就是 '当....的时候',需要回调。 应用: 定时器、 ajax、 promise、 fetch、axios

 

【关于回调函数的作用域问题】:

    var a;

    function A(callback) {
        var a = 10
        callback(); //---------【注意】:当函数B在这里调用的时候,
        //它并不能访问到a=10这个值,
    }

    function B() {

        if (a === 10) {
            console.log(a)
        } else {
            console.log('thank you')
        }
    }
    A(B);

 

【找区别】:

1.

function f2(name) {
  alert('Hello ' + name);
}

function f1(callback) {
  var name = prompt('请输入您的用户名');
  setTimeout(function () {
     callback(name);
 }, 3000);
}
f1(f2);
console.log(3333)

 

function f2(name) {
  alert('Hello ' + name);
}

function f1(callback) {
  setTimeout(function () {
    var name = prompt('请输入您的用户名');
    callback(name);
 }, 3000);
}
f1(f2);
console.log(2222)

2.

function f1() {
  var name = prompt('请输入您的用户名');
  return name
}

function f2(name) {
  alert('Hello ' + name);
}

f2(f1())
console.log(1)

 

function f1(name) {
  alert('Hello ' + name);
}

function f2(callback) {
  var name = prompt('请输入您的用户名');
  callback(name);
}
f2(f1);
console.log(2)

 

posted @ 2019-10-27 23:33  牧羊狼  阅读(163)  评论(0编辑  收藏  举报