node.js学习笔记之同步异步以及全局对象

340 阅读3分钟

同步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()清除间歇定时器