js中Promise理解与使用
这里以node.js 为例子, 使用Promise和理解
图解Promise
Promise不是异步, 它内部的处理一般是异步的
Promise基本用法
const fs = require('fs');
// resolved成功回调函数 rejected失败回调函数
const p = new Promise((resolved, rejected) => {
fs.readFile('./data/a.txt', 'utf8', (err, data) => {
if(err){
return rejected(err); // 不在继续下面的执行, 并且调用rejected失败回调
}
resolved(data); // 拿到a.txt文件内容, 执行resolved成功回调
})
})
p.then((data) => { // then(resolved, [rejected] )
console.log('执行了逻辑...也拿到data数据:', data);
},(err) => {
console.log(err);
})
- 成功:
- 失败
- 图解代码(部分改动, 道理还是一样)
Promise解决回调地狱问题
.then()的用法——return的是String、Array、Object、Function没什么用,return Promise才有用
const fs = require('fs');
// resolved成功回调函数 rejected失败回调函数
const p1 = new Promise((resolved, rejected) => {
fs.readFile('./data/a.txt', 'utf8', (err, data) => {
if (err) {
return rejected(err); // 不在继续下面的执行, 并且调用rejected失败回调
}
resolved(data); // 拿到a.txt文件内容, 执行resolved成功回调
})
})
p1.then((data) => {
console.log(data);
return 'node webpack vue react typescript'
}, (err) => {
console.log(err);
})
.then((data) => {
console.log(data);
}, (err) => {
console.log(err);
})
输出
return Promise
const fs = require('fs');
// resolved成功回调函数 rejected失败回调函数
const p1 = new Promise((resolved, rejected) => {
fs.readFile('./data/a.txt', 'utf8', (err, data) => {
if (err) {
return rejected(err); // 不在继续下面的执行, 并且调用rejected失败回调
}
resolved(data); // 拿到a.txt文件内容, 执行resolved成功回调
})
})
const p2 = new Promise((resolved, rejected) => {
fs.readFile('./data/b.txt', 'utf8', (err, data) => {
if (err) {
return rejected(err);
}
resolved(data);
})
})
p1
.then((data) => { // then(resolved, [rejected] )
console.log('执行了逻辑...也拿到data数据:', data);
return p2;
}, (err) => {
console.log(err);
})
.then((data) => { // then(resolved, [rejected] )
console.log('执行了逻辑...也拿到data数据:', data);
}, (err) => {
console.log(err);
})
输出:
’
- 图解
- 这样代码管理起来比较容易, 避免了
callback hell
Promise 的其他写法
- .then()方法第一个回调用于接收resolved回调函数, 那么同样也有一个方法接收失败的
.catch(rejectedCallback)
const fs = require('fs');
// resolved成功回调函数 rejected失败回调函数
const p1 = new Promise((resolved, rejected) => {
fs.readFile('./data/a.txt', 'utf8', (err, data) => {
if (err) {
return rejected(err); // 不在继续下面的执行, 并且调用rejected失败回调
}
resolved(data); // 拿到a.txt文件内容, 执行resolved成功回调
})
})
const p2 = new Promise((resolved, rejected) => {
fs.readFile('./data/b.txt', 'utf8', (err, data) => {
if (err) {
return rejected(err);
}
resolved(data);
})
})
p1
.then((data) => { // then(resolved, [rejected] )
console.log('执行了逻辑...也拿到data数据:', data);
return p2;
})
.catch((err) => {
console.log(err);
})
.then((data) => { // then(resolved, [rejected] )
console.log('执行了逻辑...也拿到data数据:', data);
})
.catch((err) => {
console.log(err);
})
输出结果还是一样的
这样做的目的是对成功或者失败的回调, 进行了管理, 成功或者失败的回调很多, 这样就起到了一定的管理作用, 不至于写恶心的代码
——艺术编程
对以上代码封装,减少重复度高的代码
const fs = require('fs');
function pReadFile(path) {
return new Promise((resolved, rejected) => {
fs.readFile(path, 'utf8', (err, data) => {
if (err) { // 错误终止
return rejected(err);
}
resolved(data);
})
})
}
pReadFile('./data/a.txt').then((data) => {
console.log('执行了逻辑...也拿到data数据: ', data);
return pReadFile('./data/b.txt');
})
.catch(err => {
throw err;
})
.then((data) => {
console.log('执行了逻辑...也拿到data数据: ', data);
})
.catch(err => {
throw err;
})
- 这样代码更精炼, 对于大量繁琐或者重复的代码, 个人习惯进行封装简化, 提升代码质量