nodejs异步编程

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

console.log('before');

console.log('after');

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

console.log('before');

setTimeout(

    () => { console.log('last');

}, 2000);

console.log('after');

 异步 API 执行结果需要用回调函数获取

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

同步API、异步API执行顺序

同步 API 会阻塞后面代码的执行,需要从上往下依次执行,异步 API 不会阻塞后面代码的执行

代码运行时,同步代码会放在同步代码执行区,异步代码会放在异步代码执行区和回调函数队列,等待所有同步代码完成后,再回调异步代码执行。

 


但如果需要依次按顺序执行三个异步 API 最简单的方法是不断的异步 API,但那将会造成异步编程的回调地狱问题

例如:需求依次读取 文件、文件、文件

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

这样的代码将会非常难维护

所以nodejs添加了一个 Promise 对象,目的是解决Node.js异步编程中回调地狱的问题。

Promise 对象

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 和 reject 是函数带的两个参数,在执行成功时,会在 promise.then 函数里接收 resolve 的返回值作为参数,失败则在 .catch 函数里接收 reject 的返回值作为参数。

程序可以写为如下

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

//把创建的 promise 对象作为函数返回值

p1().then((r1)=> {
	console.log(r1);
	return p2();
})
.then((r2)=> {
	console.log(r2);
	return p3();
})
.then((r3) => {
	console.log(r3)
})

异步函数

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

const fn = async () => {};

async function fn () {}

  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 返回结果
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();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值