笔记--Node.js异步编程

Node.js异步编程

1. 同步API,异步API

// 路径拼接
const public = path.join(__dirname, 'public');
// 请求地址解析
const urlObj = url.parse(req.url);
// 读取文件
fs.readFile('./demo.txt', 'utf8', (err, result) => {
    console.log(result);
});
同步API:只有当前API执行完成后,才能继续执行下一个API

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

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

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

笔记--Node.js异步编程_第1张图片

2. 同步API,异步API的区别(获取返回值)

同步API可以从返回值中拿到API执行的结果,但是异步API是不可以的
// 同步
function sum (n1, n2){
    return n1 + n2;
}
const result = sum (10, 20);

console.log(result);

// 异步
function getMsg(){
    setTimeout(function () {
        return {
            msg: 'hello node.js'
        }
    }, 2000)
}
const msg = getMsg();

console.log(msg);

在这里插入图片描述

3. 回调函数

自己定义函数让别人去调用。
// getData函数定义
function getData (callback) {}
// getData函数调用
getData { () => {} };
function getMsg(callback){
    setTimeout(function () {
        callback({
            msg: 'hello node.js'
        }) 
    }, 2000)
}
getMsg(function (data) {
    console.log(data);
});

笔记--Node.js异步编程_第2张图片

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

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

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

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

console.log('代码开始执行');

setTimeout(() => {
    console.log('2秒后执行的代码');
}, 2000);

setTimeout(() => {
    console.log('0秒后执行的代码');
}, 0);

console.log('代码执行结束');

笔记--Node.js异步编程_第3张图片
笔记--Node.js异步编程_第4张图片

5. 代码执行顺序分析

笔记--Node.js异步编程_第5张图片

6. 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('文件读取结果');

需求:依次读取A文件,B文件,C文件
回调地狱:

const fs = require('fs');

fs.readFile('./1.txt', 'utf8', (err, result1) => {
    console.log(result2);
    fs.readFile('./2.txt', 'utf8', (err, result2) => {
        console.log(result2);
        fs.readFile('./3.txt', 'utf8', (err, result3) => {
            console.log(result3);
        })
    })
});

7. Promise

Promise出现的目的是解决Node.js异步编程中的回调地狱的问题。
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)); // 失败了
const fs = require("fs");

// let promise = new Promise((resolve, reject) => {
//     fs.readFile('./1.txt', 'utf8', (err, result) => {
//         if (err != null) {
//             reject(err);
//         } else {
//             resolve(result);
//         }
//     });
// });

// promise.then((result) => {
//     console.log(result);
// })
//     .catch((err) => {
//         console.log(err);
//     })

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

在这里插入图片描述

8. 异步函数

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

const fn = async () => {};
async function fn () {}

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返回结果
// 1. 在异步函数定义的前面加上async关键字,普通函数就变成了异步函数
// 2. 异步函数默认的返回值是promise对象
async function fn () {
    return 123;
}

console.log(fn ());

在这里插入图片描述

// 1. 在异步函数定义的前面加上async关键字,普通函数就变成了异步函数
// 2. 异步函数默认的返回值是promise对象
// 3. 在异步函数内部使用throw关键字进行错误抛出

// async function fn () {
//     // throw '发生了一些错误';
//     return 123;
// }

// // console.log(fn ());

// fn().then(function (data) {
//     console.log(data);
// }).catch(function (err) {
//     console.log(err);
// })

// 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();

笔记--Node.js异步编程_第6张图片

你可能感兴趣的:(node.js,javascript)