Node.js异步编程

同步API

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

console.log('before'); 
console.log('after');

代码一行一行执行。

异步API

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

console.log('before');
setTimeout(
   () => { console.log('last');
}, 2000);
console.log('after');

在这里插入图片描述

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

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

function getMsg () { 
      setTimeout(function () { 
          return { msg: 'Hello Node.js' }
      }, 2000);
  }
  const msg = getMsg ();

在这里插入图片描述
在执行同步API或函数时,代码执行的结果是通过返回值获取到的,但异步API的的结果是无法通过返回值得到的,需要通过回调函数获取。

回调函数

1.自己定义函数让别人去调用。

// getData函数定义
 function getData (callback) {}
  // getData函数调用
 getData (() => {});

示例:

function getMsg (callback) {
    setTimeout(function () {
        callback ({ msg: 'Hello Node.js' })
    }, 2000);
}
getMsg (function (msg) { 
    console.log(msg);
});

在这里插入图片描述

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

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

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

在这里插入图片描述

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

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

在这里插入图片描述
执行步骤:
在这里插入图片描述

Node.js中的异步API

fs.readFile('./demo.txt', (err, result) => {});
var server = http.createServer();
 server.on('request', (req, res) => {});

存在问题

如果异步API后面代码的执行依赖当前异步API的执行结果,但实际上后续代码在执行的时候异步API还没有返回结果,这个问题要怎么解决呢?
比如:

fs.readFile('./demo.txt', (err, result) => {});
console.log('文件读取结果');
回调函数嵌套问题(回调地狱)
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)
		})
	})
});
promise

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

const fs = require('fs');

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)
})

在这里插入图片描述

异步函数

基于promise对象基础上进行封装

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

// 1.在普通函数定义的前面加上async关键字 普通函数就变成了异步函数
// 2.异步函数默认的返回值是promise对象
// 3.在异步函数内部使用throw关键字进行错误的抛出
// 
// await关键字
// 1.它只能出现在异步函数中
// 2.await promise 它可以暂停异步函数的执行 等待promise对象返回结果后再向下执行函数

async function p1 () {
	return 'p1';
}

async function p2 () {
	return 'p2';
}

async function p3 () {
	return 'p3';
}

async function run () {
	let r1 = await p1()
	let r2 = await p2()
	let r3 = await p3()
	console.log(r1)
	console.log(r2)
	console.log(r3)
}

run();

在这里插入图片描述
改造上文读取文件案例

const fs = require('fs');
// 改造现有异步函数api 让其返回promise对象 从而支持异步函数语法
const promisify = require('util').promisify;
// 调用promisify方法改造现有异步API 让其返回promise对象
const readFile = promisify(fs.readFile);

async function run () {
	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)
}

在这里插入图片描述
注意:
// 改造现有异步函数api 让其返回promise对象 从而支持异步函数语法

const promisify = require('util').promisify;

// 调用promisify方法改造现有异步API 让其返回promise对象

const readFile = promisify(fs.readFile);

run();

总结

async关键字

  1. 普通函数定义前加async关键字 普通函数变成异步函数

  2. 异步函数默认返回promise对象

  3. 在异步函数内部使用return关键字进行结果返回 结果会被包裹的promise对象中 return关键字代替了resolve方法

  4. 在异步函数内部使用throw关键字抛出程序异常

  5. 调用异步函数再链式调用then方法获取异步函数执行结果

  6. 调用异步函数再链式调用catch方法获取异步函数执行的错误信息

await关键字

1.await关键字只能出现在异步函数中

2.await promise await后面只能写promise对象 写其他类型的API是不不可以的

3.await关键字可是暂停异步函数向下执行 直到promise返回结果

补充知识点

浏览器中全局对象是window

在Node中全局对象式global

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值