承诺:链式超时

时间:2018-03-26 01:30:57

标签: javascript promise

Promise API没有可链接的timeout选项,但是在Steve Sanderson在NDC Conference上的演示文稿(这里是{3}}的15:31),他在fetch API上提供了一个优雅的可链接超时。它看起来像这样:

https://www.youtube.com/watch?v=9G8HEDI3K6s&feature=youtu.be&t=15m31s

这种方法的好处在于即使在超时之后,解析处理程序仍然完成(例如响应仍然被放入缓存)。他在演讲期间演示了这一点(并在上面的YouTube链接上提供)。有人知道这个可链接的超时是如何实现的吗?

1 个答案:

答案 0 :(得分:1)

我通常使用Promise.race来实现超时。通常情况下,我没有尝试过这个可链接的,但这是一个很酷的主意,所以我马上就试试吧。

这就是我通常用它来实现超时的方法:

function timeout (promise, duration) {
    return Promise.race([
        promise,
        new Promise((resolve, reject) => {
            setTimeout(
                () => reject(new Error("Timeout")), 
                duration
            )
        })
    ]);
} 

timeout(fetch("something"), 5000)
    .then(() => {
        // ... Operation completed without timeout ...
    })
    .catch(err => {
        // ... An error occurred possibly a timeout ...
    ));

您可以通过将函数附加到Promise类的原型(可能取决于您实际使用的promise库)来使这个可链接:

Promise.prototype.timeout = function (duration) {
    return Promise.race([
        this,
        new Promise((resolve, reject) => {
            setTimeout(
                () => reject(new Error("Timeout")), 
                duration
            )
        })
    ]);
};

fetch("something")
    .then(() => ...) // This executes before the timeout.
    .timeout(5000)
    .catch(err => ...);