异步操作
正常我们在执行保证执行顺序的异步操作的同时会导致回调地狱的情况
callBackHell demo:
const fs = require('fs');
// 假如我们要删除hehe.js文件时要看文件是否存在然后再去删除,
// 再或者删除后再新建一个新的hehe.js文件,再或者新建后再....
// 此时就会导致回调地狱
fs.stat('./hehe.js', (err, status) => {
if (err) {
console.log('no such directory here.');
} else {
fs.unlink('./hehe.js', (err) => {
console.log('unlink success ');
fs.writeFile('./hehe.js', 'xxx', (err) => {
//..... more oprations ....
})
})
}
});
你会发现此时程序已经非常难读,很难维护了;(
解决办法之一: promise对象 链式调用
1.template:
function test(){
return Promise((resolve , reject)=>{
// 需要的异步处理
...
// 成功的地方 resolve
...
// 失败处 reject
...
})
}
2. 根据顺序 形成链式调用
test().then().then().catch();
3. 捕获错误
无论哪个then() 出错后都会跳到catch()方法.
手动控制then结束可以通过手动创建 err 对象 抛出一个错误 此时程序会跳入catch 方法.
理解这种操作很重要 因为在nodejs中异步操作很重要 (这也是它很好的支持高并发的原因)
来写个小demo:
const fs = require('fs');
function isExist() {
return new Promise((resolve, reject) => {
fs.stat('./hehe.js', (err, stats) => {
console.log('stats : ' + stats);
if (err) {
reject('文件不存在');
} else {
resolve('文件存在');
}
})
})
}
function delfile() {
return new Promise((resolve, reject) => {
fs.unlink('./hehe.js', (err) => {
if (err) {
reject('fail');
} else {
resolve('ok');
}
})
})
}
isExist().then(() => {
console.log('is exist 成功处理');
return delfile();
}).then(() => {
console.log('删除文件成功处理');
//手动终止 跳入catch方法
throw new Error('手动终止后不会创建新文件');
// 这段代码是为了测试时不用每次都手动创建新文件
// 所以删除文件如果成功后再次创建同名新文件
fs.writeFile('./hehe.js', '', (err) => {
if (err) { console.log('重新创建hehejs失败'); }
})
}).then(() => {
console.log('sdadsa');
}).then(() => {
console.log('ewqqwewqewq');
}).catch((err) => {
console.log('err : ' + err);
});
/* 一组链式调用 只需要一个catch
如何手动终止链式调用? throw new err
*/
如果 有throw new Error()程序的输出有
z@mbp % node promise_catch.js
stats : [object Object]
is exist 成功处理
删除文件成功处理
err : Error: 手动终止后不会创建新文件
后面两个then中的console.log并未输出
如果无throw new Error()输出有
% node promise_catch.js
stats : [object Object]
is exist 成功处理
删除文件成功处理
sdadsa
ewqqwewqewq
字母正常输出了
可以看到在引入Promise对象后 不需要在无休止的使用回调函数(错误的回调优先)了,也防止了括号套括号的出现.