2019-10-30Node.js异步编程

1.1同步API,异步API

当中的API:有的通过返回值拿到结果,有的通过函数返回值方式拿到结果。
例如:

// 返回值拿到
// 路径拼接
const public = path.join(__dirname,'public');
// 请求地址解析
const urlObj = url.parse(req.url);
// 函数返回值
// 读取文件
fs.readFile('./demo.txt,'utf8',(err,result)=>{
         console.log(result);
});

为什么会有这两种方式?
===============================.
什么是同步API?
只有当前API执行完成后,才能继续执行下一个API
例如:

console.log('before');
console.log('after');
// 只有第一个执行完,才能执行第二个。这就是同步API,代码从上到下一行一行的执行,只有上一行代码执行完成,才能执行下一行代码。

什么是异步API?
当前API的执行,不会阻塞后面代码的执行!
例如:

console.log('before');
setTimeout(
()=>{console.log('last');
},2000)
console.log('after');
// 结果:先输出before,再输出after,2s后输出了last,(PS:虽然定时器代码在after前面,但是程序在执行到定时器代码时,并没有等待定时器代码执行完成,再执行after这个方法,在当前代码中定时器就是异步API,程序不需要等待异步API执行完成之后,再继续执行后面的代码,也就是说异步API不会阻塞后续代码的执行。)

在Node.js中异步API无处不在,掌握异步异步API,异步编程非常重要。

1.2同步API,异步API的区别(获取返回值)

同步API可以从返回值中拿到API执行的结果,但是异步API不可以。
例子:

// 同步
function sum (n1 ,n2){
         return n1 + n2;
}
const result =  sum(10,20);

// 异步
function getMsg(){
    setTimeout(function(){
         return{msg:'Hello Node,js'}
    },2000);
    //return undefined
}
const msg = getMsg();
console.log(msg);      

思考:是否能拿到函数返回值?

执行后返回: undefind

PS: 原因:当使用函数名getMsg函数名去调用getMsg()函数时,由于异步API不会阻塞代码的执行,所以在函数的底部直接return undefind(PS:因为没有写return,所以他默认返回的就是undefined,然后再过2秒后,他在setTimeout函数内部返回了一个对象,此时返回值早已拿到了undefined,然后直接进行了输出)

结论:在异步API中,无法通过返回值的方式去拿到异步API的执行结果。

1.3回调函数

那么异步API的返回值到底该怎么拿到?
实际上是通过回调函数拿到的,什么是回调函数,实际上就是自己定义函数,让别人去调用函数(看下面例子))

// getData函数定义
function getData(callback){}
//getData函数调用
getData(()=>{});
// callback仅仅是形参的名字,那么这个形参对应的实参实际上是一个函数,将一个函数作为另外一个函数的参数(没有问题),callback就是一个回调函数,在调用getData的时候传递了一个匿名函数(函数的定义,实际上这个函数在getData方法的内部调用,根据实际的情况决定是否要调用,来决定什么是要调用,这个参数就是回到函数)。

在代码编辑器中新建一个文件callback.js

function getData(callback){
    callback();
}
getData(function(){
    console.log('callback函数被调用了')
});

命令行工具执行node callback.js

返回:callback函数被调用了
// 这就是回调函数其中一种表现形式

函数写成这个样子有什么用?

function getData(callback){
    callback('123');              // 给callback传递参数 123
}
getData(function(n){          // 在这个函数里拿到123这个实参,使用形参n对象这个实参
    console.log('callback函数被调用了')
    console.log(n);
});

返回:callback函数被调用了
123

PS:123被输出了。如果getData这个函数在内部有异步操作,在异步操作执行完成之后,就可以调用callback('123')这个回调函数,并且把异步API执行的结果通过参数的形式传递给callback,那么我们在getData里面的回调函数里面就能够拿到异步API执行的结果。

回到第一个例子:

function getMsg(callback){
    setTimeout(function(){
       callback({
            msg:'hello node.js'
    }) 
    },2000);
}
getMsg(function(data){
  console.log(data);
});    

命令行执行

返回:{mag:'hello node.js'}
PS:通过回调函数的方式拿到了异步API执行的结果。

1.4同步API,异步API的区别(代码执行顺序)

同步API从上到下一次执行,前面代码没有执行完成之前,后面的代码不能执行

for(var i=0;i<100000;i++){
console.log(i);
}
console.log('for循环后面的代码');

PS:先执行for循环10万次,在for循环没有执行完成之前,后面的console.log()是不能执行的。

异步API不会等待API执行完成后再向下执行

console.log('代码开始执行');
setTiomeout(()=>{console.log('2S后执行的代码')},2000);
setTiomeout(()=>{console.log('0S后执行的代码')},0);
console.log('代码结束执行');

返回:代码开始执行
代码结束执行
0S后执行的代码
2S后执行的代码

总结:同步代码执行区→异步代码执行区→回调函数队列
同步执行完成后,再异步代码执行区执行(完成后),再去回调函数队列,再将队列中的回调函数放入同步代码执行区执行。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,635评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,543评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,083评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,640评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,640评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,262评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,833评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,736评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,280评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,369评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,503评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,870评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,340评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,460评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,909评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,512评论 2 359

推荐阅读更多精彩内容

  • 弄懂js异步 讲异步之前,我们必须掌握一个基础知识-event-loop。 我们知道JavaScript的一大特点...
    DCbryant阅读 2,713评论 0 5
  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宫若石阅读 1,088评论 0 1
  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 9,223评论 0 3
  • Node.js 常用工具 util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScr...
    FTOLsXD阅读 536评论 0 2
  • Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函...
    neromous阅读 8,710评论 1 56