同步API
只有当前API执行完成之后,才会继续执行下一个API
异步API
当前API的执行不会阻塞后续代码的执行,程序不会等待异步API执行完再继续执行
两者的区别
同步API可以从返回值当中拿到返回的结果;异步API不可以从返回值当中拿到结果
function res(){
setTimeout(()=>{
return 'msg';
},2000)
}
let msg = res();//定时器不会阻塞代码的执行,所以在定时器下面隐含的有一句`return undefined`语句
console.log(msg);//undefined
怎么拿到异步API的返回值?
回调函数拿到返回值
function res(callback){
setTimeout(()=>{
callback('msg');
},2000)
}
res((data)=>{
console.log(data);//msg
});
Node.js代码执行顺序
先按顺序执行同步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);
})
})
});
解决回调地狱问题:Promise
作用:可以将异步API的执行和处理结果分离,将处理得到的结果拿到外面处理,将异步API的代码放在Promise里面
//异步API的执行和处理完成的数据分离
let promise = new Promise((resolve, reject)=>{
let flag = true;
setTimeout(()=>{
if (flag){
resolve(flag);
}else{
reject('error')
}
},2000)
});
promise.then((flag)=>{
console.log(flag);
}).catch((err)=>{
console.log(err);
});
//Promise解决回调地狱
function p1() {
return new Promise((resolve, reject) => {
fs.readFile('./1.txt', 'utf8', (err, result3) => {
resolve(result3);
})
});
}
function p2() {
return new Promise((resolve, reject) => {
fs.readFile('./2.txt', 'utf8', (err, result3) => {
resolve(result3);
})
});
}
function p3() {
return new Promise((resolve, reject) => {
fs.readFile('./3.txt', 'utf8', (err, result3) => {
resolve(result3);
})
});
}
p1().then(res => {
console.log(res);
return p2();
}).then(res => {
console.log(res);
return p3();
}).then(res => {
console.log(res);
});
解决回调地狱 异步函数
异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不再有回调函数嵌套,使代码变得清晰明了。 使用:在普通函数定义前面加上async,普通函数就变成了异步函数;异步函数默认的返回值是promise对象,不需要自己创建promise对象返回。
const fn = async () => {} ;
async funtion fn(){}
async function func(param) {
if (param){
throw '发生了一些错误';//使用throw抛出错误,作用类似于reject
}
return '123';//代替了resolve
}
//使用then catch处理
func(true).then(res => {
console.log(res);//true
}).catch(err => console.log(err));
await关键字:可以暂停异步函数的执行,await后面紧跟一个promise对象,会等待promise对象返回结果之后才继续执行。
async function pf1() {
return 'p1';
}
async function pf2() {
return 'p2';
}
async function pf3() {
return 'p3';
}
async function run() {
let p1 = await pf1();//暂停异步函数run的执行,等待pf1返回结果
let p2 = await pf2();
let p3 = await pf3();
console.log(p1, p2, p3);//p1 p2 p3
}
run();
小例子:
//异步读取文件
const fs = require('fs');
//改造现有异步函数API,让其返回Promise对象,从而支持async await写法
const promisify = require('util').promisify;
const readFile = promisify(fs.readFile);//改造readFile方法,使其可以返回promise对象
async function run() {
let res1 = await readFile('./1.txt', 'utf8');
let res2 = await readFile('./2.txt', 'utf8');
let res3 = await readFile('./3.txt', 'utf8');
console.log(res1, res2, res3);//1 2 3
}
run();
全局对象global
浏览器中全局对象时window,node中全局对象是global Node中全局对象下有以下方法,可以在任何地方使用,global可以省略。
- console.log0在控制台中输出
- setTimeout()设置超时定时器
- clearTimeout()清除超时时定时器
- setlnterval()设置间歇定时器
- clearlnterval()清除间歇定时器