以前都只在文章里看到地狱回调,知道用 promise 来解决地狱回调。
今天终于实践了 使用 Promise 解决地狱回调问题
。首先看下面地狱回调的具体例子。
// 以小程序中发现 http 请求为例
wx.request({
url: "https://xxxx.com/拿数据1",
method: "GET",
success(res => {
//数据1是拿数据2的前置条件
wx.request({
url: "https://xxxx.com/拿数据2",
data: res,
method: "POST",
success(res => {
//数据2是拿数据3的前置条件
....
})
})
})
})
这段代码是可以跑的,逻辑也十分正确。但这种 无限套娃
的写法,让人看的眼花缭乱,尤其是当里面还进行 js 逻辑处理时,代码更是不堪入目。
这就是我们常说的地狱回调问题。主要影响的就是代码的 美观性、可维护性
。
那么正确的写法应该怎样?下面看看用 Promise
的写法
new Promise((reslove, reject) => {
wx.request({
url: "https://xxxx.com/拿数据1",
method: "GET",
success(数据1 => {
reslove(数据1)
})
})
}).then(数据1 => {
return new Promise((reslove, reject) => {
wx.request({
url: "https://xxxx.com/拿数据2",
data: 数据1,
method: "POST",
success(数据2 => {
reslove(数据2)
})
})
})
}).then(数据2 => {
return new Promise((reslove, reject) => {
wx.request({
url: "https://xxxx.com/拿数据3",
data: 数据2,
method: "POST",
success(数据3 => {
reslove(数据3)
})
})
})
}).then(数据3 => {
....
})
视觉上是不是比回调地狱好看多了?
但这样依然不是最优解,我们来结合 设计模式之 - 简单工厂模式
来优化一下
function getData1() {
return new Promise((reslove, reject) => {
wx.request({
url: "https://xxxx.com/拿数据1",
method: "GET",
success(数据1 => {
reslove(数据1)
})
})
})
})
}
function getData2(数据1) {
return new Promise((reslove, reject) => {
wx.request({
url: "https://xxxx.com/拿数据2",
data: 数据1,
method: "POST",
success(数据2 => {
reslove(数据2)
})
})
})
})
}
function getData3(数据2) {
return new Promise((reslove, reject) => {
wx.request({
url: "https://xxxx.com/拿数据3",
data: 数据2,
method: "POST",
success(数据3 => {
reslove(数据3)
})
})
})
})
}
function getFinallyData() {
getData1().then(data1 => {
getData2(data1)
}).then(data2 => {
getData3(data2)
}).then(data3 => {
....
})
}
这样就完成啦!值得注意的是,我第一次看到这个用法时,曾误解了一个地方:
function getFinallyData() {
getData1().then(data1 => {
getData2(data1).then(data2 => {
getData3(data2 => {
....
})
})
})
}
then的位置写错了,当时的我并不知道怎么回事儿。实际上就是还不明白什么叫 解决地狱回调问题 ,有没有和我犯过一样错误的萌新呢?