编程语言
首页 > 编程语言> > javascript – 如何添加polyfill以支持Edge中的finally()?

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 with undefined), Promise.resolve(2).finally(() => {}) will be resolved with 2.

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

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().

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

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