网站首页 > 基础教程 正文
学习背景
上一章我们学习了同步和异步,了解了他们的优缺点。nodejs单线程模型为防止线程被阻塞.提供了大量的异步函数和异步IO。这一章中我们学习一下异步函数的实现方式。
实现同步
正常同步的代码看起来比较的简单,都自上而下逐步执行的。执行完这行才会执行下一行,比如执行一个加减乘除的运算。
实现异步
但是异步执行就没有那么简单直观,需要在调用的时候注册执行完成的通知,可以是回调方式也可以是事件通知,也可以是发布订阅。
callback 方案
- 概念
这个是js中异步的经典用法,callback称为回调,指在调用异步方法的时候传一个回调方法,等异步任务执行完毕后,自动调用这个回调方法。
- 代码
function a(callback) {
console.log("A:执行完再其他函数");
callback();
}
function b(callback) {
console.log("B:执行完再其他函数");
callback()
}
function c(callback) {
console.log("C:执行完再其他函数");
callback()
}
function test() {
a(() => {
console.log('A:执行完了,进入回调')
b(() => {
console.log('B:执行完了,进入回调')
c(() => {
console.log('C:执行完了,进入回调')
})
})
})
}
test()
输出顺序为
A:执行完再其他函数
A:执行完了,进入回调
B:执行完再其他函数
B:执行完了,进入回调
C:执行完再其他函数
C:执行完了,进入回调
- 总结
虽然callback方案简单直观,但是在顺序执行多个异步任务的时候容易嵌套多层回调函数,形成“回调地狱”,代码可读性下降,维护成本变高。为了解决这个问题,nodejs引入了primise的概念。
事件EventEmitter方案
- 概念
事件在html前端用的比较多,尤其是在处理用户点击事件。它包含事件监听者和事件触发者,监听者监听一个事件标志,等待事件触发者来触发这个事件标志。同时也可以用在异步处理上,当异步任务处理完成后可以触发完成事件,其他地方监听这个完成事件来监听异步任务的完成状态。
- 代码
const EventEmitter = require('events').EventEmitter;
const myEvent = new EventEmitter();
myEvent.on('finish', function () {
console.log('finish 事件触发');
});
setTimeout(function () {
myEvent.emit('finish');
}, 1000);
- 总结
event事件常用在多个事件或者多个回调的场景下,但是我们自己定义异步方法的时候用事件来实现并不是特别好。
发布订阅方案
发布订阅模式和事件有着异曲同工之妙,它里面包含三个模块分别是发布者,订阅者和处理中心。有点像报社发布报纸,报社是发布者,订阅者是订阅该报纸的用户。这一章节我们先知道有这个方案,后面我会再写详细的说明教程。
约定Promise方案
- 概念
字面理解Promise是约定的意思,这个是ES6中原生提供的一个对象。它出现的目的是为了解决callback方案遗留的问题
- 代码
const promiseA = new Promise(function (resolve, reject) {
console.log("AAA:start");
setTimeout(() => {
resolve()
}, 100)
});
const promiseB = new Promise(function (resolve, reject) {
console.log("BBB:start");
setTimeout(() => {
resolve()
}, 50)
});
promiseA.then(() => {
console.log("AAA:finish")
});
promiseB.then(() => {
console.log("BBB:finish")
})
执行结果
AAA:start
BBB:start
BBB:finish
AAA:finish
- 总结
这么看promise 并没有比callback好用太多,甚至可以理解为把callback分装成then 方法。但是promise有官方支持的语法糖async、await,通过这两个语法糖可以实现用同步的方法去写异步。下一章我们把promse这个知识点单独拎出来讲,如何用同步的方式去实现异步。
猜你喜欢
- 2024-10-12 Serverless Web Function 实践教程(一):快速部署 Node.js Web 服务
- 2024-10-12 nodejs入门教程之Promise(十) nodejs实战教程
- 2024-10-12 node.js入门教程(一)发送邮件 nodejs发送文件到客户端
- 2024-10-12 JavaScript教程:之安装Node.js和npm
- 2024-10-12 Node js 本地环境安装及设置和包管理工具常用命令使用教程
- 2024-10-12 Node-RED教程 – 43 – 日期多种格式化显示
- 2024-10-12 宝塔面板安装NodeJS程序并配置https教程
- 2024-10-12 nodejs入门教程之同步与异步(八) nodejs入门基础教程
- 2024-10-12 Node-RED教程 – 50 – 动态改变显示内容的角度
- 2024-10-12 Node-RED教程 – 07 – 通过网址url链接读写modbus从站
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)