如何在 Edge 中添加 polyfill 以支持 finally()? [英] How to add a polyfill to support finally() in Edge?

查看:18
本文介绍了如何在 Edge 中添加 polyfill 以支持 finally()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 axios 库并使用 then()、catch() 和 finally().在 Chrome 中完美运行.然而,finally() 方法在 MS Edge 中不起作用.我研究过使用 polyfills 或垫片,但我迷路了.我没有使用 webpack 或转译,也不打算添加它们.我需要保持这个简单.如何添加 polyfill 以确保 finally() 在 Edge 中工作?谢谢!

I'm using axios library and using then(), catch() and finally(). Works perfectly in Chrome. However the finally() method does not work in MS Edge. I researched using polyfills or shims and I'm lost. I am not using webpack or transpiling and don't plan to add them. I need to keep this simple. How can I add a polyfill to make sure finally() works in Edge? Thanks!

推荐答案

这应该处理 thenable 的 species 以及下面详述的行为:

This should handle the propagation of the thenable's species in addition to the behaviors detailed below:

Promise.prototype.finally = Promise.prototype.finally || {
  finally (fn) {
    const onFinally = callback => Promise.resolve(fn()).then(callback);
    return this.then(
      result => onFinally(() => result),
      reason => onFinally(() => Promise.reject(reason))
    );
  }
}.finally;

此实现基于 finally() 并依赖于 then() 符合规范:

This implementation is based on the documented behavior of finally() and depends on then() being compliant to the specification:

  • finally 回调将不会收到任何参数,因为没有可靠的方法来确定承诺是被履行还是被拒绝.此用例正好适用于您不关心拒绝原因或履行值的情况,因此无需提供.

  • 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.

Promise.resolve(2).then(() => {}, () => {}) 不同(将使用 undefined), Promise.resolve(2).finally(() => {}) 将使用 2 解析.

Unlike Promise.resolve(2).then(() => {}, () => {}) (which will be resolved with undefined), Promise.resolve(2).finally(() => {}) will be resolved with 2.

类似的,不像 Promise.reject(3).then(() => {}, () => {})(会用 undefined), Promise.reject(3).finally(() => {}) 将被 3 拒绝.

Similarly, unlike Promise.reject(3).then(() => {}, () => {}) (which will be fulfilled with undefined), Promise.reject(3).finally(() => {}) will be rejected with 3.

注意: finally 回调中的 throw(或返回一个被拒绝的承诺)将拒绝新的承诺,并指定拒绝原因调用 throw().

Note: A throw (or returning a rejected promise) in the finally callback will reject the new promise with the rejection reason specified when calling throw().

当然还有等效行为的演示:

And of course a demonstration of equivalent behavior:

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

// run test on native implementation
test('native');

// force Promise to use the polyfill implementation
Promise.prototype.finally = /* Promise.prototype.finally || */ {
  finally (fn) {
    const onFinally = callback => Promise.resolve(fn()).then(callback);
    return this.then(
      result => onFinally(() => result),
      reason => onFinally(() => Promise.reject(reason))
    );
  }
}.finally;

// run test on polyfill implementation
test('polyfill');

function test (impl) {
  const log = ordinal => state => logger(`${ordinal} ${impl} ${state}`);
  const first = log('first');

  // test propagation of resolved value
  delay(2, 1000)
    .finally(first('settled'))
    .then(first('fulfilled'), first('rejected'));

  const second = log('second');

  // test propagation of rejected value
  delay(Promise.reject(3), 2000)
    .finally(second('settled'))
    .then(second('fulfilled'), second('rejected'));

  const third = log('third');

  // test adoption of resolved promise
  delay(4, 3000)
    .finally(third('settled'))
    .finally(() => delay(6, 500))
    .then(third('fulfilled'), third('rejected'));

  const fourth = log('fourth');

  // test adoption of rejected promise
  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 对这个答案的投入.请参阅他的实现,如果您觉得这篇文章有帮助,也请点赞.

Thanks to @Bergi for his input on this answer. Please see his implementation and upvote it as well if you found this post helpful.

这篇关于如何在 Edge 中添加 polyfill 以支持 finally()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆