我仍然不熟悉JavaScript中的所有这些异步内容,在处理一些承诺时我遇到了一些令人困惑的情况。这是我目前的代码:
exists(filename, targetDir){
const filepath = path.join(targetDir || this.getTargetDir(), filename);
// plug in any one method from below
}
当我查看其他人的代码时,我看到他们正在解析这样的值(插入上面的代码):
// method 1
return request(this.getUrl(filepath))
.then(res => {
return Promise.resolve(res.statusCode === 200);
})
.catch(() => {
return Promise.resolve(false);
});
// method 2
return request(this.getUrl(filepath))
.then(res => {
Promise.resolve(res.statusCode === 200);
})
.catch(() => {
Promise.resolve(false);
});
// method 3
return request(this.getUrl(filepath))
.then(res => {
return res.statusCode === 200;
})
.catch(() => {
return false;
});
// method 4
return new Promise((resolve, reject) => {
request(this.getUrl(filepath))
.then(res => {
resolve(res.statusCode === 200);
}
.catch(() => {
resolve(false);
};
});
在这种情况下哪些是正确的?哪些不正确?它取决于场景吗?推荐哪一个?感谢您的好解释,谢谢!
澄清: exists
是一个类方法,它返回一个解析为布尔值的Promise,其中true
表示URL存在,而false
表示它不存在。
澄清#2: exists
如果发生错误,应解析为false
。
答案 0 :(得分:4)
方法1 是正确但不必要的复杂。
方法2 是完全错误的。
你创建了新的Promises,但是它们没有在任何地方填充,因此它们在函数结束时被处理掉。
它相当于:
return request(this.getUrl(filepath)).catch(err => undefined);
方法3 是最好的方法。
方法4 也会解析为corect值,但它是一个反模式。
What is the explicit promise construction antipattern and how do I avoid it?
答案 1 :(得分:1)
下一个.then()
会收到当前.then()
返回的内容。如果此返回值恰好是一个承诺,则在承诺解决后执行下一个.then()
。
使用方法3,您可以将其他.then()
附加到当前链:
exists('test.txt', '/')
.then(doesExist => console.log(doesExist ? 'The file exists.' : 'The file doesn\'t exist.'));
这也可以通过方法1和方法4实现,但方法1不必要地将值包装在将立即解决的承诺中。
方法4不必要地将整个请求包装在一个承诺中。这称为explicit-construction anti-pattern。
方法2不允许承诺链接。您无法使用Promise.resolve
中包含的值,因为.then()
和.catch()
都会隐式返回undefined
。