下面是对Node.js异步编程的整理,希望可以帮助到有需要的小伙伴~

文章目录

  • 同步API,异步API
  • 同步API,异步API的区别
    • 获取返回值的方式不同
    • 代码执行顺序不同
  • Node.js中的异步API
  • Promise
  • 通过Promise解决回调地狱
  • 异步函数

同步API,异步API

同步API:只有当API执行完成后,才能继续执行下一个API

异步API:当前API的执行不会阻塞后续代码的执行

// 同步编程
/*
console.log("before");
console.log("after");
// before
// after
*/// 异步编程
console.log('before');
setTimeout(() => {console.log('last')},2000);console.log('after');
/*
before
after
last
// before执行后,2秒钟后再执行last,在这2秒钟的时间里after执行了
*/

同步API,异步API的区别

获取返回值的方式不同

同步API可以从返回值中拿到API执行的结果

异步API必须通过回调函数拿到异步操作的执行结果

通过回调函数获取异步函数的返回值

回调函数:

别人调用自己定义的函数

// 回调函数的定义
function getData (callback) {}
// 回调函数的调用
getData ( ()=>{} );// getData()里面的实参()=>{} 对应的是 callback形参;即在getData()函数内部调用了()=>{}函数

通过回调函数获取异步函数的返回值示例:

/* function getMsg () {setTimeout(function () {return {msg:'hello node.js'}},2000)
}const msg = getMsg();
console.log(msg); // undefined// 2秒后才可以执行定时器里面的内容
// 所以返回值是函数的默认返回值undefined */// 可以通过回调函数获取到异步操作的执行结果
function getMsg (callback) {setTimeout(function () {callback({msg:'hello node.js'})},2000)
}getMsg(function (data){console.log(data); // { msg: 'hello node.js' }
})

代码执行顺序不同

Node.js从上而下依次执行代码

遇到同步API就拿到同步代码执行区去执行

遇到异步API就拿到异步代码执行区,但是不会执行异步代码,

当所有的同步代码执行完毕后,再到异步代码执行区依次执行代码

当异步代码执行完毕后,系统会去回调函数队列中找异步API对应的回调函数,把回调函数放到同步代码执行去区执行

同步API从上到下依次执行,前面代码会阻塞后面代码的执行

for (var i=0;i<10;i++) {console.log(i)
}
console.log("循环外")
// 0 1 2 3 4 5 6 7 8 9 循环外

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

console.log('代码开始执行')
setTimeout(function(){console.log('2s后执行')
},2000)setTimeout(function(){console.log('0s后执行')
})console.log('代码结束执行')/* 代码开始执行
代码结束执行
0s后执行
2s后执行 */

Node.js中的异步API

异步编程的返回结果是通过回调函数获取的

在异步编程中,前面代码的执行不会阻碍后面代码的执行,但是有时候后面代码的执行会依赖前面代码的执行结果,这时可以通过多个回调函数来完成。

读取文件就是通过回调函数返回结果的,如果依次读取多个文件,就需要多次调用回调函数

示例如下:

// 依次读取1.txt、 2.txt 、 3.txt文件// 导入文件模块
const fs = require('fs');
// 读取文件
fs.readFile('./1.txt','utf8',(err,result1) => {console.log(result1)fs.readFile('./2.txt','utf8',(err,result2) => {console.log(result2)fs.readFile('./3.txt','utf8',(err,result3) => {console.log(result3)})})
})
/*
// 结果:
1
2
3
*/

如果需要写很多个回调函数的话,就会造成回调地狱,promise可以解决回调地狱问题。

Promise

Promise出现的目的是解决Node.js异步编程中回调地狱的问题。

Promise是一个构造函数

Promise语法

let promise = new Promise((resolve,reject) => {setTimeout ( () => {if (true) {resolve({name:'张三'})} else {reject('失败了')}},2000)
})
promise.then(result => console.log(result)); // {name:'张三'}.catch(error => console.log(error)); // 失败了
  • resolve:将异步API的执行结果传递到整个Promise的外面(resolve是一个方法)
  • reject:如果异步API执行失败,就把失败的结果传递到整个Promise的外面 (reject是一个方法)

通过Promise对象的then方法获取到异步的执行结果。

通过Promise解决回调地狱

// 依次读取1.txt、 2.txt 、 3.txt文件// 导入文件模块
const fs = require('fs');
const { resolve } = require('path');
// 读取文件
/* fs.readFile('./1.txt','utf8',(err,result1) => {console.log(result1)fs.readFile('./2.txt','utf8',(err,result2) => {console.log(result2)fs.readFile('./3.txt','utf8',(err,result3) => {console.log(result3)})})
}) */function p1() {return new Promise((resolve,reject) => {fs.readFile('./1.txt','utf8',(err,result) => {resolve(result)})})
}function p2(){return new Promise((resolve,reject) => {fs.readFile('./2.txt','utf8',(err,result) => {resolve(result);})})
}function p3(){return new Promise((resolve,reject) => {fs.readFile('./3.txt','utf8',(err,result) => {resolve(result);})})
}p1().then((r1) => {console.log(r1);return p2();
})
.then((r2) => {console.log(r2);return p3();
})
.then((r3) => {console.log(r3);
})// 相当于/* p1().then((r1) => {console.log(r1);
});p2().then((r2) => {console.log(r2);
});p3().then((r3) => {console.log(r3);
}); *//*
// 结果:
1
2
3
*/

异步函数

使用Promise可以解决回调地狱的问题,但是会产生代码冗余,可以使用ES 7提供的回调函数解决回调地狱的问题并且代码更加简单明了。

异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不再有回调函数嵌套,使代码变得清晰明了。

const fn = async () => {};

async关键字:

  1. 普通函数定义前加async关键字普通函数变成异步函数
  2. 异步函数默认返回promise对象
  3. 在异步函数内部使用return关键字进行结果返回,结果会被包裹在promise对象中
  4. return关键字代替了resolve方法
  5. 在异步函数内部使用throw关键字抛出程序异常
  6. 调用异步函数再链式调用then方法获取异步函数执行结果
  7. 调用异步函数再链式调用catch方法获取异步函数执行的错误信息

await关键字:

  1. await关键字只能出现在异步函数中
  2. await promise ;await后面只能写promise对象写其他类型的API是不可以的
  3. await关键字可是暂停异步函数向下执行直到promise返回结果

示例:

const fs = require('fs');
// fs中readFile()方法的返回结果不是Promise类型的,不能使用异步函数中的await关键字
// uitl模块的promisify()方法可以将返回的结果改为Primise类型
// 没有调用promisify方法,没有写promisify()
// 改在现有异步函数的API,让其返回promise对象,从而支持异步函数语法
const promisify = require('util').promisify;
// 调用了promisify()方法,但没有调用readFile()方法
// 调用promisify方法改造现有异步API,让其返回promise对象
const readFile = promisify(fs.readFile);async function run() {// 调用readFile()方法,该方法的返回结果回改成promise类型let r1 = await readFile('./1.txt','utf8')let r2 = await readFile('./2.txt','utf8')let r3 = await readFile('./3.txt','utf8')console.log(r1)console.log(r2)console.log(r3)
}run();// 返回结果:
// 1
// 2
// 3

end~
对Node.js异步编程的介绍到这里就结束啦~
希望可以对你有所帮助~
如果有错误,请大佬指正,万分感谢!

Node.js异步编程~超级详细哦相关推荐

  1. 57 Node.js异步编程

    技术交流QQ群:1027579432,欢迎你的加入! 欢迎关注我的微信公众号:CurryCoder的程序人生 1.Node.js异步编程 1.1 Node.js中的异步API 如果异步API后面的代码 ...

  2. node.js异步编程

    目录 1.同步API 2.异步API 回调地狱 用promise解决回调地狱 异步函数 Node服务器端编程 1.同步API 只有在当前的API执行完成后,才执行下一个API.代码的执行方式是按照代码 ...

  3. Node.js 异步编程(附几个小练习题学会分析代码执行顺序)

    1. 同步API,异步API 同步API:只有当前API执行完成后,才能继续执行下一个API console.log('before'); console.log('after'); 异步API:当前 ...

  4. 前端学习(1319):node.js异步编程

    test,js function getMsg(callback) {setTimeout(function() {callback({msg: 'hello node js'})}, 2000) } ...

  5. await原理 js_深入浅出node.js异步编程 及async await原理

    最近看了一些文章对于async await的原理及概念的解析,我觉得很多时候有些不太准确. 尤其是对于async和await会阻塞线程的说法更是有些扯淡了,JS本身就是单线程的语言如果await会阻塞 ...

  6. Node.js 异步编程之 Callback介绍

    原文:http://www.jb51.net/article/63070.htm ------------------------------------- Node.js 基于 JavaScript ...

  7. promise 浏览器实现的源码_【大前端01-01】函数式编程与JS异步编程、手写Promise...

    [简答题]一.谈谈你是如何理解JS异步编程的,EventLoop.消息队列都是做什么的,什么是宏任务.什么是微任务? 如何理解JS异步编程 众所周知JavaScript语言执行环境是"单线程 ...

  8. Node.js高级编程【一】node 基础

    目录 一.Node 基础 1.课程概述 2.Node.js 架构 3.为什么是Node.js ? 4.Node.js 的 异步IO 5.Node.js 主线程是单线程 6.Node.js 应用场景 7 ...

  9. js 异步执行_JS Asynchronous — JS 异步编程极简史

    Asynchronous JS 异步编程极简史,这个故事网上已经很多人有了自己的讲述. Event Loop 解释了 Node.js 为何以及如何实现单线程服务模型和 Event Loop.对于 JS ...

最新文章

  1. 虚指针的用法(原出处//http://blog.csdn.net/haoel/article/details/1948051)
  2. python爬取网页公开数据_如何用Python爬取网页数据
  3. 报名 | CCKS 2021评测任务:生活服务领域知识图谱问答
  4. uniapp 子组件 props拿不到数据_Vue组件间的几种通信方式
  5. 关于文件系统权限的管理
  6. [css] 行内元素可以设置padding和margin吗?
  7. 使用ASP.NET 2.0 Profile存储用户信息
  8. JavaScript 流行度最高,Java 屈居第三! | 2020 最新软件开发状况报告
  9. LeetCode 59. Spiral Matrix II
  10. list排序成员函数对string对象与char*对象排序的差别
  11. Spring Boot: 加密应用配置文件敏感信息
  12. FreeBSD NetBSD OpenBSD DragonFlyBSD 操作系统
  13. Winfrom 定时锁屏
  14. 分析方法论_用户生命周期的建立
  15. 互联网产品需求分析思路与方法
  16. spring事务的传播行为的讲解(笔记 侵删)
  17. Android 调用相机拍照并保存
  18. 尚硅谷大数据技术之Kettle
  19. JAVA反射中的Accessible
  20. 三星显示屏测试软件,LCD随意调 三星MagicTune软件全体验

热门文章

  1. 外连接OUTER JOIN(三十五)
  2. debian 8 和centos 配置java 环境变量的正确姿态
  3. IOS开发之多线程 -- GCD的方方面面
  4. 分享自TERRY-V 《Qt Creator生成带图标的exe文件》
  5. Stream - Web大文件上传插件
  6. HDU2023 求平均成绩【入门】
  7. JSK-135 数字加1【大数】
  8. CCF NOI1115 找数
  9. I00035 完美数(Perfect number)
  10. pandas 学习(五)—— datetime(日期)