使用Promise解决回调地狱的问题?
一、如果使用普通的函数嵌套调用,会形成回调地狱
// 使用Promise解决回调地狱的问题
// 导入fs模块
const fs = require('fs')
function getReadFile(fpath) {
var promise = new Promise(function (resolve, reject) {
fs.readFile(fpath, 'utf-8', (err, dataStr) => {
if (err) return reject(err)
resolve(dataStr)
})
})
// 返回promise
return promise
}
// 需求:先读取文件1,在读取文件2,在读取文件3
// 错误的示范
getReadFile('./files/1.txt').then(
(data) => {
console.log(data + '读取文件1成功')
getReadFile('./files/2.txt').then(
(data) => {
console.log(data + '读取文件2成功')
getReadFile('./files/3.txt').then(
(data) => {
console.log(data + '读取文件3成功')
},
(err) => {
console.log(err + '读取文件3失败')
}
)
},
(err) => {
console.log(err + '读取文件2失败')
}
)
},
(err) => {
console.log(err.message + '读取文件失败')
}
)
二、解决办法
// 使用Promise解决回调地狱的问题
// 导入fs模块
const fs = require('fs')
function getReadFile(fpath) {
var promise = new Promise(function (resolve, reject) {
fs.readFile(fpath, 'utf-8', (err, dataStr) => {
if (err) return reject(err)
resolve(dataStr)
})
})
// 返回promise
return promise
}
// 需求:先读取文件1,在读取文件2,在读取文件3
// 正确的操作
getReadFile('./files/1.txt')
.then(
(data) => {
console.log(data + '读取文件1成功')
// 将promise实例返回出去,避免了回调地狱的问题
return getReadFile('./files/2.txt')
},
(err) => {
console.log(err.message + '读取文件1失败')
}
)
.then(
(data) => {
console.log(data + '读取文件2成功')
// 将promise实例返回出去,避免了回调地狱的问题
return getReadFile('./files/3.txt')
},
(err) => {
console.log(err.message + '读取文件2失败')
}
)
.then(
(data) => {
console.log(data + '读取文件3成功')
},
(err) => {
console.log(err.message + '读取文件3失败')
}
)
运行结果:
三、Promise两种捕获异常的方式?
3.1. 需求:哪怕前面的 Promise 执行失败了,但是,不要影响后续的 Promise 的执行,此时,我们可以单独为 每个 Promise, 通过 .then 指定以下失败的回调;getReadFile('./files/1.txt')
.then(
(data) => {
console.log(data + '读取文件1成功')
return getReadFile('./files/2.txt')
},
(err) => {
console.log(err.message + '读取文件1失败')
return getReadFile('./files/2.txt')
}
)
.then(
(data) => {
console.log(data + '读取文件2成功')
return getReadFile('./files/3.txt')
},
(err) => {
console.log(err.message + '读取文件2失败')
return getReadFile('./files/3.txt')
}
)
.then(
(data) => {
console.log(data + '读取文件3成功')
},
(err) => {
console.log(err.message + '读取文件3失败')
}
)
执行结果:
3.2. 需求:后续的promise执行,依赖于 前面的Promise执行的结果,如果前面的Promise执行失败了,则后面的就没有继续执行下去的必要了,此时,一旦有报错,则终止所有的Promise
getReadFile('./files/1.txt')
.then((data) => {
console.log(data + '读取文件1成功')
return getReadFile('./files/2.txt')
})
.then((data) => {
console.log(data + '读取文件2成功')
return getReadFile('./files/3.txt')
})
.then((data) => {
console.log(data + '读取文件3成功')
})
.catch((err) => {
// catch 的作用:如果前面有任何的Promise执行失败,则立即终止所有的Promise的执行,并马上进入catch去处理Promise中抛出的异常。
console.log(err.message)
})
执行结果: