js回调函数例子_(译)JavaScript:什么是回调

29a1507c84f7387fae31607fd6983151.png

译者的话

真正意义上接触JavaScript已经接近一年,关于JS的核心概念其实就只有几个,但是每段时间再重新回味总会产生不一样的化学反应。今天刚好看到再Medium上面看到一篇讲回调函数的文章,重新读了一遍,又有了新的理解。想当初自己当初刚刚接触这个概念的时候搜罗了很多文章,都不能很好地理解,果然知识需要慢慢沉淀。但当时更多地是把回调跟异步编程扯上关系才会导致对这个概念的理解变得纠结。跳出了异步,发现回调本身也是一种编程思想。翻译这篇文章的目的,还是为了浅显易懂的文章分享给大家,另外还能锻炼自身阅读英文的能力。

原文地址: https:// codeburst.io/javascript -what-the-heck-is-a-callback-aba4da2deced ,
作者:Brandon Morelli

通过简单的例子,只需6分钟就能学习和理解回调函数的基本概念。

什么是回调

简单来讲:回调是在另一个函数执行完成之后再被执行的函数。--因此它的名字叫回调

更深入来讲,在JavaScript中,函数是一个对象。正因为如此,函数可以作为函数的参数出现,而且可以作为结果值被返回。这种函数称为高阶函数(higher-order functions)。任何可以作为参数被传递的函数称为回调函数。

这样看起来有很多概念,现在让我们来列举一些例子来剖析它。

为什么需要回调

其中一个很重要的原因是JavaScript是一种事件驱动的语言。这意味着,在继续运行之前,JavaScript不等待响应,它会继续监听其他事件往下执行。现在来看一个简单的例子:

function first(){
  console.log(1);
}
function second(){
  console.log(2);
}
first();
second();

在你的预期当中,函数 first 会先被执行,接着函数 second 再被执行,下面是控制台的打印结果:

// 1
// 2

目前为止看起来都很好,但如果函数 first 包含一些不能被立即执行的代码呢?举个例子,我们发送一个需要等待响应的API请求,为了模拟这种情况,我们打算使用 setTimeout 这个定时出发函数。我们将延迟500毫秒触发这个函数用来模拟发送API请求的情况。代码如下:

function first(){
  // Simulate a code delay
  setTimeout( function(){
    console.log(1);
  }, 500 );
}
function second(){
  console.log(2);
}
first();
second();

setTimeout() 函数此时是如何运行并不是最重要的。最重要的我们将console.log(1); 的执行放在500毫秒之后。当我们调用函数时会发生什么?

first();
second();
// 2
// 1

虽然 first() 函数先被调用,但打印的结果却在 second() 函数。

这并不意味着说JavaScript不按照我们规定的顺序执行,而是JS不会选择等待 first 函数继续执行时才开始执行 second 函数。

所以这说明什么?因为你不能调用一个接一个的函数并希望它们按照正确的顺序执行。回调是一种确保代码在其他代码已经执行完毕之后再开始运行的方式

创建回调

说了那么多,现在来创建一个回调。

首先,打开你的谷歌开发者工具控制台,将下面的函数声明编辑进你的控制台:

function doHomework(subject) {
  alert(`Starting my ${subject} homework.`);
}

上面我们创建了doHomework 函数。我们的函数接收一个变量,这个参数代表我们验证的主题。现在通过底下的代码在控制台上调用函数。

doHomework('math');
// Alerts: Starting my math homework.

现在加上回调作为 doHomework() 函数的最后一个参数,这个回调函数被定义在doHomework的第二个参数。

function doHomework(subject, callback) {
  alert(`Starting my ${subject} homework.`);
  callback();
}

doHomework('math', function() {
  alert('Finished my homework');
});

如你所见,如果你编辑以上代码在控制台上你将看到两个alert紧接着出现,先是"starting homework" ,再是 "finished my homework"。

但是并不总是必须在函数调用中定义。也可以在其他地方定义:

function doHomework(subject, callback) {
  alert(`Starting my ${subject} homework.`);
  callback();
}
function alertFinished(){
  alert('Finished my homework');
}
doHomework('math', alertFinished);

运行结果跟之前的例子一样,但是设置方式有些不同。你可以看到,在doHomework 函数调用时,我们将alertFinished 函数定义作为参数传递。

一个现实的例子

上周我发布了一篇文章讲如何用38行代码去实现TwitterBot。这些代码在那篇文章中代码能生效的唯一原因就是因为TwitterAPI。当你向API发请求时,在对响应的内容进行操作之前你必须要先等待响应。这就是现实生活的完美的关于回调的例子。接下来让我们来看看这个请求是怎么样的:

T.get('search/tweets', params, function(err, data, response) {
  if(!err){
    // This is where the magic will happen
  } else {
    console.log(err);
  }
})
  • T.get 仅仅意味着我们发送一个GET请求
  • 这个请求里有三个参数:‘search/tweets’,这是我们的请求路径,params 代表搜索参数,还有一个匿名函数作为我们的回调

回调在这里非常重要,因为我们需要从服务器得到响应之后才能进一步执行代码。我们不需要知道在通过GET请求发送参数之后API请求是否成功。一旦Twitter响应,我们的回调函数将被调用。Twitter将发送err(错误)对象或者response对象返回给我们。在回调函数里面,我们可以使用if语句去确定我们请求是否成功,然后相对应地对新数据进行操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值