// 路径拼接
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');
同步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);
自己定义函数让别人去调用。
// getData函数定义
function getData (callback) {}
// getData函数调用
getData { () => {} };
function getMsg(callback){
setTimeout(function () {
callback({
msg: 'hello node.js'
})
}, 2000)
}
getMsg(function (data) {
console.log(data);
});
同步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('代码执行结束');
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);
})
})
});
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);
})
异步函数是异步编程语法的终极解决方案,他可以让我们将异步代码写成同步的形式,让代码不在有回调函数嵌套,
使代码变得清晰明了。
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();