连续使用 promise
之前在学习 promise 时,有看到使用 promise 避免回调函数嵌套回调函数,以方便阅读和理解代码。大概意思类似于下面的代码:
// 定义函数, 返回promise
function loadImageAsync(url) {
return new Promise(function(resolve, reject) {
const image = new Image();
image.onload = function() {
resolve(image);
};
image.onerror = function() {
reject(new Error('Could not load image at ' + url));
};
image.src = url;
});
}
// 调用函数, 通过返回 promise 避免在回调函数内使用回调函数
loadImageAsync(url)
.then(res => {
return loadImageAsync(url);
})
.then(res => {
console.log('then NO2');
})
.catch(e => {
console.log(e);
})
返回一个 promise 对象,而不是在回调函数里再写回调函数
loadImageAsync(url)
.then(res => {
loadImageAsync(url)
.then(res => {}) // 回调函数内嵌套回调函数
.catch(e => {})
})
.catch(e => {})
后来在写代码的时候就用上了,刚开始用的很爽,但后来碰到了一些意外情况:有的回调函数内可能需要再调用回调函数,此时可以返回一个 promise,但某些情况下并不需要再回调,例如
function loadImageAsync(url) {
return new Promise(function(resolve, reject) {
const image = new Image();
image.onload = function() {
console.log('successed')
resolve(image);
};
image.onerror = function() {
reject(new Error('Could not load image at ' + url));
};
image.src = url;
});
}
loadImageAsync(url)
.then(res => {
if (!res) { // 某些条件,判断是否需要回调
return loadImageAsync(url);
} else {
// TODO 不需要回调
}
})
.then(res => {
// 此时 then 是一直存在的
console.log('then 2');
})
.catch(e => {
// if (!e) retrun; 或者
e && console.log(e);
})
这种情况下,then 一直存在,当没有返回任何对象时,相当于返回了一个 resolve 的 promise ,后面 then 其中的内容总会执行,但此时其实是不需要执行这些内容的。
这种情况下由两种办法,第一种,还把回调写里边,就不说了,另一种,返回一个 reject 的 promise,else 里的代码如下
} else {
return new Promise((resolve, reject) => {
// reject(new Error('something wrong'));
reject();
});
}
但这会由一个问题,即使没有发生错误,只是返回一个 promise,也会出发 catch,会处理 error,可以将 reject 函数的参数设置为空,或者其他方式,然后在 catch 中增加一种情况进行处理。