我正在使用axios库,并使用then(),catch()和finally()。在Chrome中完美运行。但是,finally()方法在MS Edge中不起作用。我使用填充胶或垫片进行了研究,但我迷路了。我不使用webpack或转译,也不打算添加它们。我需要保持简单。如何添加polyfill以确保finally()在Edge中工作?谢谢!
答案 0 :(得分:8)
这实际上比我想象的要难。除以下详述的行为外,这甚至还应处理随后的species
的传播:
Promise.prototype.finally = Promise.prototype.finally || {
finally (fn) {
const onFinally = cb => Promise.resolve(fn()).then(cb);
return this.then(
result => onFinally(() => result),
reason => onFinally(() => Promise.reject(reason))
);
}
}.finally;
此实现基于finally()
的已记录行为,并且取决于then()
是否符合规范:
finally
回调将不会接收任何参数,因为没有可靠的方法来确定诺言是否已兑现。正是这种用例适用于您不关心拒绝原因或实现价值,因此不需要提供它的情况。与
Promise.resolve(2).then(() => {}, () => {})
(将由undefined
解决)不同,Promise.resolve(2).finally(() => {})
将由2
解决。类似地,与
Promise.reject(3).then(() => {}, () => {})
(将由undefined
实现)不同,Promise.reject(3).finally(() => {})
将被3
拒绝。注意::
throw
回调中的finally
(或返回被拒绝的承诺)将以调用throw()
时指定的拒绝原因来拒绝新的承诺。
当然还有等效行为的演示:
const logger = (label, start = Date.now()) => (...values) =>
console.log(label, ...values, `after ${Date.now() - start}ms`);
const delay = (value, ms) => new Promise(resolve => setTimeout(resolve, ms, value));
test('native');
// force Promise to use the polyfill implementation
Promise.prototype.finally = /* Promise.prototype.finally || */ {
finally (fn) {
const onFinally = cb => Promise.resolve(fn()).then(cb);
return this.then(
result => onFinally(() => result),
reason => onFinally(() => Promise.reject(reason))
);
}
}.finally;
test('polyfill');
function test (impl) {
const log = ordinal => state => logger(`${ordinal} ${impl} ${state}`);
const first = log('first');
delay(2, 1000)
.finally(first('settled'))
.then(first('fulfilled'), first('rejected'));
const second = log('second');
delay(Promise.reject(3), 2000)
.finally(second('settled'))
.then(second('fulfilled'), second('rejected'));
const third = log('third');
delay(4, 3000)
.finally(third('settled'))
.finally(() => delay(6, 500))
.then(third('fulfilled'), third('rejected'));
const fourth = log('fourth');
delay(5, 4000)
.finally(fourth('settled'))
.finally(() => delay(Promise.reject(7), 500))
.then(fourth('fulfilled'), fourth('rejected'));
}
.as-console-wrapper{max-height:100%!important}
感谢@Bergi在此答案上的投入。如果您认为这篇文章有帮助,请参阅his implementation并对其进行投票。