js解决异步回调地狱方式
当想使js中异步多个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对象
有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise
对象提供统一的接口,使得控制异步操作更加容易。Promise 也有一些缺点。首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise
内部抛出的错误,不会反应到外部。第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
const fs = require('fs');
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)
})
虽然 Promise 已经普及,但是 Node.js
里仍然有大量的依赖回调的异步函数,如果我们每个函数都封装一次,也是齁麻烦齁麻烦的,比齁还麻烦。所以 Node8 就提供了 util.promisify() 这个方法,方便我们快捷的把原来的异步回调方法改成返回 Promise
实例的方法,接下来,想继续用队列,还是 await 就看需要了。
1.在普通函数定义的前面加上async关键字 普通函数就变成了异步函数
2.异步函数默认的返回值是promise对象
3.在异步函数内部使用throw关键字进行错误的抛出
await关键字
1.它只能出现在异步函数中
2.await promise 它可以暂停异步函数的执行 等待promise对象返回结果后再向下执行函数
const fs = require('fs');
// 改造现有异步函数api 让其返回promise对象 从而支持异步函数语法
const promisify = require('util').promisify;
// 调用promisify方法改造现有异步API 让其返回promise对象
const readFile = promisify(fs.readFile);
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();
Tags : node.js