【发布时间】:2019-03-20 05:45:08
【问题描述】:
可以构造一个从不拒绝的 Promise 吗?我的意思是这是某种反模式还是可以接受的?让我用一个例子来说明这一点。我有一个类 ModifyURL,它由许多方法组成,每个方法对 URI 字符串数组执行一些操作并返回一个 Promise。部分实现如下所示。
class ModifyURL {
constructor() {
}
/**
* Remove empty and invalid urls
* @param {object} object containing arrays of links
*
* @return {object} object containing arrays of valid links
*/
removeInvalid(data) {
return new Promise((resolve,reject)=>{
for (let key in data) {
data[key] = data[key].filter( function(item) {
return !(item == '#' || !item || item == ' ');
});
}
resolve(data)
});
}
/**
* Remove duplicates
* @param {object} object containing arrays of links
*
* @return {object} object containing arrays of unique links
*/
removeDuplicates(data) {
return new Promise((resolve,reject)=>{
for (let key in data) {
data[key] = data[key].filter(function (item, pos) {
return data[key].indexOf(item) == pos;
})
}
resolve(data)
});
}
/**
* Add full hostname to relative urls.
* @param {object} object containing arrays of links
* @param {string} hostname to be added if link is relative
*
* @return {object} object containing arrays of absolute links
*/
fixRelativeLinks(data,hostname) {
if(typeof data === 'object'){
return new Promise((resolve,reject)=>{
for (let key in data) {
data[key].forEach((v, i) => {
if(data[key][i]){
data[key][i] = URL.resolve(hostname, data[key][i])
}
})
}
resolve(data)
})
}
}
}
稍后我将这些 Promise 链接起来,它工作正常。
modifyURL.removeInvalid(data).then(res=>{
return res
})
.then(()=>{
return modifyURL.fixRelativeLinks(data, res.request.href)
})
.then(modifyURL.removeDuplicates).then(res=>{
onSuccess(res)
}).catch(err=>{console.log(err)})
正如你所注意到的,我不使用 reject,感觉有点奇怪。原因是最后我需要接收一些数据。即使链中的某些 Promise 未能完成他们的任务,我也需要最终 resolve 使用我的 URI 字符串数组。这就是我不拒绝的原因,因为它破坏了我的Promise链。但是如果没有 reject,我将失去正确跟踪错误的能力。处理此类任务的正确方法是什么?
【问题讨论】:
-
如果你从不做任何异步操作,那么 Promise 的意义何在?这种将所有内容都包装在 Promise 中的方式对我来说看起来很糟糕。
-
如果您的代码是同步的,请将其保留为函数而不是承诺;您仍然可以将结果链接到 promise 链中,也可以将其用作普通函数。
-
如果
Promise构造函数的执行器函数(接受resolve和reject参数的函数)抛出错误,则忽略你没有做任何异步的事实,构造的promise隐式转换到拒绝状态,所以你很好。但是,如果可能发生不会抛出的错误,或者在构造函数中创建的异步回调的承诺链,您需要检查这些条件并使用您自己的用户定义的错误调用reject()。事实上,如果你的构造函数中有任何 Promise,你就不应该使用它。 -
@przemoo83 不,这样不行。如果 API 或网络出现故障,您绝对应该拒绝该承诺。否则你的调用者将永远无法处理错误。
-
@przemoo83 “保持 Promise 链正常工作”到底是什么意思?你能举个例子吗?你应该只在链的中间使用
.catch(e => substituteResult),它会返回一个新的promise,即使之前的promise失败了,也会用替代结果来实现。
标签: javascript promise