javascript – 如何添加polyfill以支持Edge中的finally()?
作者:互联网
我正在使用axios库并使用then(),catch()和finally().在Chrome中完美运行.但是finally()方法在MS Edge中不起作用.我研究过使用polyfills或垫片,我迷路了.我没有使用webpack或转换,也不打算添加它们.我需要保持这个简单.如何添加polyfill以确保finally()在Edge中有效?谢谢!
解决方法:
这实际上比我想象的要困难一些.除了下面详述的行为之外,这甚至应该处理theable 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()
是否符合规范:
A
finally
callback will not receive any argument, since there’s no reliable means of determining if the promise was fulfilled or rejected. This use case is for precisely when you do not care about the rejection reason, or the fulfillment value, and so there’s no need to provide it.Unlike
Promise.resolve(2).then(() => {}, () => {})
(which will be resolved withundefined
),Promise.resolve(2).finally(() => {})
will be resolved with2
.Similarly, unlike
Promise.reject(3).then(() => {}, () => {})
(which will be fulfilled withundefined
),Promise.reject(3).finally(() => {})
will be rejected with3
.Note: A
throw
(or returning a rejected promise) in thefinally
callback will reject the new promise with the rejection reason specified when callingthrow()
.
当然还有等效行为的演示:
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并对其进行投票.
标签:polyfills,javascript,promise,finally 来源: https://codeday.me/bug/20191002/1842820.html