用 finally() 执行清理

目前有一个提议 (尚未成为 ECMAScript 标准的一部分)将 finally 回调添加到承诺中,无论承诺是履行还是拒绝,承诺都将被执行。从语义上讲 ,这类似于 tryfinally 子句

你通常会使用此功能进行清理:

var loadingData = true;

fetch('/data')
    .then(result => processData(result.data))
    .catch(error => console.error(error))
    .finally(() => {
        loadingData = false;
    });

重要的是要注意 finally 回调不会影响承诺的状态。它返回的价值无关紧要,承诺保持在之前的履行/拒绝状态。因此,在上面的示例中,即使 finally 回调返回 undefined,也会使用 processData(result.data) 的返回值来解析 promise。

由于标准化过程仍在进行中,你的承诺实施很可能不会支持开箱即用的 finally 回调。对于同步回调,你可以使用 polyfill 添加此功能:

if (!Promise.prototype.finally) {
    Promise.prototype.finally = function(callback) {
        return this.then(result => {
            callback();
            return result;
        }, error => {
            callback();
            throw error;
        });
    };
}