首页 > 编程语言 >彻底理解 Node.js 中的回调(Callback)函数

彻底理解 Node.js 中的回调(Callback)函数

时间:2023-06-29 09:33:36浏览次数:37  
标签:Node function 调用 console 函数 callback timer js Callback

究竟什么是回调函数(Callback),网上有许许多多的文章,大部分看得人云里雾外,这些文章大概分成两类,第一类堆砌了太多的术语,基本上不明白术语就没法看,另一类反过来,不讲术语,完全是举一些脱离编程的生活化例子来类比,看的人更加晕头转向。

作为JS的核心,回调函数和异步执行是紧密相关的,不跨过这个门槛,很多回调代码能把人看晕!

引用stack overflow 上大神的描述 其实callback 很简单也很纯粹:

A "callback" is any function that is called by another function which takes the first function as a parameter. (在一个函数中调用另外一个函数就是callback)

以下是一个最简单的例子:

function a() {
    return 1
}
 
function b(aa) {
    return 2 + aa
}
 
//调用:
var c=0
c = b(a()) //A是个函数,但它又作为一个参数在B函数中被调用
console.log(c) //结果显示3

以上例子极易理解,下面再引入另一个概念:异步

看以下代码:

var a = 0
 
function bb(x) {
    console.log(x)
}
 
function timer(time) {
    setTimeout(function () {
        a=6
    }, time);
}
 
//调用:
console.log(a)
timer(3000)
bb(a)

以上代码很简单,我们需要的逻辑是,全局变量a初值为0,然后过3秒后,让它为6,然后再打印出来,看上去,上面的代码没有问题,理论上符合我们的逻辑需求,但却发现结果是这样:

0
0

咋回事?

因为JS是一种异步执行语言,尽管timer函数内让a=6了,但是JS不会死等时间结束再跳出函数,而是马上就会执行下一步语句(即调用bb函数),但这时候3秒钟根本就没结束,a还没有被重新赋值,所以打印出来还是为0。

用回调函数可以解决这个问题:

var a = 0
 
function bb(x) {
    console.log(x)
}
 
function timer(time, callback) {
    setTimeout(function () {
        a = 6
        callback(a);
    }, time);
}
 
//调用:
console.log(a)
timer(3000,bb)

这次,在timer函数中添加了一个关键字callback,意思就是说此处不是一个普通的参数,而是一个函数名,打起精神,关键的地方来了:

一般而言,函数的形参是指由外往内向函数体传递变量的入口,但此处加了callback后则完全相反,它是指函数体在完成某种使命后调用外部函数的出口!这时候应该明白什么叫"回调"了吧,也就是回头调用外部函数的意思。

在本例中,当3秒钟到了后,首先a=6,然后通过关键字callback(a)调用了函数bb(x),结果显示:

0
6

这个逻辑,符合我们的需求。

在写法上,也可以不需要定义函数bb, 直接在调用timer的时候写成function形式,把调用部分改成这样也可以,效果完全一样:

console.log(a)
timer(3000, function (x) {
    console.log(x)
})

这种写法函数名都不需要了(术语称为"匿名函数"),在nodejs代码中更为常见也更好理解,翻译成自然语言就是:定时3秒,完成后再回头调用function(x)里面的内容。

nodejs编程中大量使用了异步编程技术,这是为了高效使用硬件,同时也可以不造成同步阻塞。其实nodejs在底层还是通过多线程技术实现的异步操作,但普通用户并不需要深究它的实现方法,我们只要做好我们的异步处理即可。

标签:Node,function,调用,console,函数,callback,timer,js,Callback
From: https://www.cnblogs.com/weifeng1463/p/17513169.html

相关文章

  • 自用gulp打包脚本,压缩html,压缩js,压缩css,压缩图片,功能齐全
    constgulp=require('gulp');constfs=require('fs');consthtmlmin=require('gulp-htmlmin');constuglify=require('gulp-uglify');constuglifyEs=require('uglify-es');constminifyCSS=require(......
  • ExtJs学习
    ExtExt.onReady:准备函数,执行时机是DOM对象加载完毕后JS三种函数构造形式arguments对象接受函数的实际参数用于做递归操作使用call指定函数执行的作用域函数.call(window,10,20,30),(作用域对象,参数1,参数2,参数3)apply作用一样,但是是传数组函数.apply(window,[2,3,4])......
  • NodeJS系列(5)- ECMAScript 6 (ES6) 语法(三)
    在“NodeJS系列(3)-ECMAScript6(ES6)语法(一)”和“NodeJS系列(4)-ECMAScript6(ES6)语法(二)”里,我们介绍并演示let、const、Symbol、函数扩展、类等ES6语法和概念。本文在“NodeJS系列(2)-NPM项目Import/ExportES6模块”的npmdemo项目的基础上,继续介绍并演示Ref......
  • delphi如何把json传递过来的base64值转成图片
    资料来原:https://blog.csdn.net/red_eye/article/details/129634709   在Delphi中,您可以使用TNetEncoding.Base64.DecodeString方法将JSON传递过来的Base64编码字符串转换为原始二进制数据。然后,您可以将该二进制数据保存为图像文件或将其加载到TImage组件中以显示图像。以......
  • 10redis列表操作,其他操作,redis管道,django中使用redis,django缓存,序列化json和pickle,cel
    字符串和字节转换的两种方式#字符串和字节转换的两种方式 -decode,encode-直接类型转换-bytes格式的16进制,2进制,10进制的显示#字符串需要用encode,bytes格式需要用decode,但是有时候忘了#可以直接进行强转b1=bytes(s,encoding='utf-8') print(......
  • 使用exceljs和file-saver导出带图片的excel表格
    参考https://www.swvq.com/article/detail/487https://github.com/exceljs/exceljs/blob/master/README_zh.md#图片importExcelJSfrom'exceljs'importfileSaverfrom'file-saver'letworkbook=nullletworksheet=null//图片转base64constco......
  • end io callback
      ext4fsendiocallback(mpage_end_io)mpage_end_io+0x0/0x1c8bio_endio+0x1cc/0x22cblk_update_request+0x1e8/0x484mmc_blk_mq_complete_rq+0x28/0xb0mmc_blk_mq_complete+0x34/0x40blk_done_softirq+0x88/0xf8_stext+0x128/0x49c__irq_exit_rcu.llvm.4269462......
  • 图书商城Vue+Element+Node项目练习(...)
    本系列文章是为学习Vue的项目练习笔记,尽量详细记录一下一个完整项目的开发过程。面向初学者,本人也是初学者,搬砖技术还不成熟。项目在技术上前端为主,包含一些后端代码,从基础的数据库(Sqlite)、到后端服务Node.js(Express),再到Web端的Vue,包含服务端、管理后台、商城网站、小程序/App,分......
  • js promise对象数组,使用reduce序列化执行
    自己使用mdn官方例子测试了一下,发现还有一些小问题,调试了一下OK了。consttimeOut=function(ms){ returnnewPromise(function(resolve){ returnsetTimeout(resolve,ms); })}varp1=function(){ returnnewPromise(function(resolve){ console.log(newDate()+'......
  • fastjson将date转换成了long
     记录一个bug,这个问题是使用fastjson的时候遇到了将date的数据转换成long类型而不是转换成string环境fastjson使用的是1.2.76造成的原因更具环境大家可能已经猜测到了真实的原因-版本太低造成的。这个项目的存在时间比较久所以在使用的依赖上版本比较低,除了源码之外......