异步编程
1.node.js工作原理
1.1同步方式执行
代码一行一行执行,下一行的代码必须等待上一行代码执行完成后才能执行;
1.2异步方式
代码在执行过程中某行代码需要耗时,代码执行不会等待耗时操作完成以后再去执行下一行代码,而不是等待直接向后执行,异步代码的执行结果需要通过回调函数的方式处理;
1.3代码执行顺序
console.log('代码开始执行');
setTimeout(() => {
console.log('2秒后执行的代码');
}, 2000);
setTimeout(() => {
console.log('"0秒"后执行的代码');
}, 0);
console.log('代码结束执行');
2.Promise
1.Promise
出现的目的是为了解决node.js
异步编程中的回调地狱问题;
2.Promise
本身是一个构造函数,要使用promise
解决回调地狱的问题,需要使用new
运算符创建Promise
构造函数的实例对象;
在创建对象的时候需要传入一个匿名函数,匿名函数中有两个参数resolve,reeject
;
const fs = require('fs');
//promise的目的`是为了解决回调函数地狱
let promise = new Promise((resolve,reject)=>{
fs.readFile('./1.txt','utf8',(err,result)=>{
if(err != null){
//文件读取错误时调用的函数,并且输出错误信息
reject(err);
}
else{
//正确的时候调用resolve函数,输出正确信息
resolve(result);
}
})
})
// promise.then就是文件读取正确时的信息
//链式的,后边跟上.catch就是文件读取错误时输出错误信息
promise.then((result)=>{
console.log(result);
}).catch((err)=>{
console.log(err);
})
3.异步函数
异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不在有回调嵌套,代码变得简洁易懂;
const fn = async () => {};
async function fn() {};
async
1.普通函数定义前边加async
关键字,普通函数变为异步函数;
2.异步函数默认返回promise
对象;
3.在异步函数内部使用return
关键字进行结果返回,结果会被包裹的promise
对象中,return
关键字代替了resolve
方法;
4.在异步函数内部使用throw
关键字抛出程序异常;
5.调用异步函数再链式调用then
方法获取异步函数执行结果;
6.调用异步函数再链式调用catch
方法获取异步函数执行的错误信息;
await
await只出现在异步函数中;
await promise await后面只能写promise对象,写其他的类型的API是不可以的;
await关键字 可以暂停异步函数的执行,等待promise对象返回结果后再向下执行函数;
// 在普通函数定义的前边加上async关键字,普通函数就变成了异步函数
async function p1(){
return 'p1';
}
async function p2(){
return 'p2';
}
async function p3(){
return 'p3';
}
// 异步函数默认的返回值是promise对象
console.log(p1()) //打印p1函数的返回值,Promise { 'p1' } 是promise对象
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();
4.promisify
改造函数
// 改造现有异步函数api 让其返回promise对象 从而支持异步函数语法
const promisify = require('util').promisify;
// 调用promisify方法改造现有异步API 让其返回promise对象
const readFile = promisify(fs.readFile);
const fs = require('fs');
//改造现有异步函数api,让其返回promise对象,从而支持异步函数语法
//引入系统模块util下边的方法promisify方法
const promisify = require('util').promisify;
//调用promisify方法改造现有异步API 让其返回promise对象 promise的目的是为了解决回调函数地狱
const readFile = promisify(fs.readFile);
// 普通函数定义前边加上async关键字,普通函数就会变为异步函数,异步函数返回值为promise对象
//await关键字只能出现在异步函数中
// await promise await后面只能写promise对象,写其他类型不可以
//await 关键字可是暂停异步函数向下执行,知道promise返回结果
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)
}
run();