用 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;
        });
    };
}