从承诺中解析价值的哪种方式是正确的?

时间:2017-08-13 17:35:59

标签: javascript ecmascript-6 promise

我仍然不熟悉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

2 个答案:

答案 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)

方法3是最好的。

下一个.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