为什么我的Vue项目中的promise.finally在Edge中不起作用?


15

让我的polyfill在Edge中工作时遇到了很大的麻烦。我尝试了各种尝试,但都没有按照文档进行操作。这似乎是有希望的。最后特别是那是行不通的。这是在vuex模块中发生的,因此我尝试将vuex添加到vue.config中的transpileDependencies,但是没有运气。

在此处输入图片说明

我的babel.config.js:

module.exports = {
  presets: [['@vue/cli-plugin-babel/preset', {
    useBuiltIns: 'entry',
  }]],
};

在我的main.js中,最顶部有以下两个导入:

import 'core-js/stable';
import 'regenerator-runtime/runtime';

我的vue.config.js

// eslint-disable-next-line import/no-extraneous-dependencies
const webpack = require('webpack');

const isProd = process.env.NODE_ENV === 'production';

module.exports = {
  configureWebpack: {
    // Set up all the aliases we use in our app.
    plugins: [
      new webpack.optimize.LimitChunkCountPlugin({
        maxChunks: 6,
      }),
    ],
  },
  css: {
    // Enable CSS source maps.
    sourceMap: !isProd,
  },
  transpileDependencies: ['vuex'],
};

请注意,如上所述,我已经尝试过使用或不使用transpileDepedencies。这里说VUE /巴贝尔,预置的应用程序es7.promise.finally被列为默认的填充工具

版本:

  • 微软Edge:44.18
  • 微软EdgeHTML 18.18362
  • @ vue / cli-plugin-babel“:“ ^ 4.1.2”
  • “ core-js”:“ ^ 3.6.4”
  • “ regenerator-runtime”:“ ^ 0.13.3”

更新13/02

因此,我尝试在我的网站的边缘中键入Promise.prototype,但看起来确实是多填充的: 这里

因此,目前我正在调查链中的某些部分(axios / vue axios)是否未返回承诺。由于它在镀铬中工作,我怀疑链的一部分未正确填充吗?

这是我的整个连锁店:

/* VUEX MODULE ACTION */  
[a.ALL_CUSTOMERS](context) {
    context.commit(m.SET_CUSTOMER_LOADING, true);
    CustomerService.getAll()
      .then(({ data }) => {
        context.commit(m.SET_CUSTOMERS, data);
      })
      .finally(() => context.commit(m.SET_CUSTOMER_LOADING, false));
  },

/* CUSTOMER SERVICE */
import ApiService from '@/common/api.service';
const CustomerService = {
  getAll() {
    const resource = 'customers/';
    return ApiService.get(resource);
  },
...
}

/* API SERVICE */
import Vue from 'vue';
import axios from 'axios';
import VueAxios from 'vue-axios';

const ApiService = {
  init() {
    Vue.use(VueAxios, axios);
    let baseUrl = process.env.VUE_APP_APIURL;
    Vue.axios.defaults.baseURL = baseUrl;
  },

  setHeader() {
    Vue.axios.defaults.headers.common.Authorization = `Bearer ${getToken()}`;
  },

  get(resource) {
    this.setHeader();
    return Vue.axios.get(`${resource}`);
  },
  ...
}

3
有趣的是,Edge不需要polyfill,因为它finally()从v18开始就支持Promise
Daniel

出于好奇,什么是EdgeHTML版本?您可以在找到Edge版本的下方找到它。我问是因为CanIUse基地对此提供了支持。来自他们的网站:*Version number used for Edge is based on the number of EdgeHTML rather than Edge itself. This is because EdgeHTML is the engine for Edge that is related to feature support change.
Tanner

Microsoft EdgeHTML 18.18362
J.Kirk。

2
Edge应该告诉您,这是一个承诺。而是说这是一个对象。因此,返回的对象不是预期的承诺。
Mouser

2
通过提供简化的回购来重现该问题,以便其他人可以提供帮助,可以改善此问题。像codeandbox.io这样的网站可以用于此目的。
Jair Reina

Answers:


1

我以前曾经遇到过这个问题。直到最后在Edge上不起作用。我终于像下面的VVV一样进行了更新,并且有效。

这应该处理thenable的传播品种除了详述如下行为:

Promise.prototype.finally = Promise.prototype.finally || {
  finally (fn) {
    const onFinally = value => Promise.resolve(fn()).then(() => value);
    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拒绝。

注意:finally回调中的throw(或返回被拒绝的promise)将以调用throw()时指定的拒绝原因拒绝新的promise。


0

这是core-js中的一个已知问题。

从理论上讲,Edge最终提供了Promise polyfill,但是功能检测或浏览器列表可能正在发生某些情况,因此您需要提供polyfill:shrug:

我会从您的项目中删除Vue babel插件和core-js,然后npm重新安装它们。

  • npm install @vue/cli-plugin-babel --save-dev

  • npm install core-js --save

另外,请确保在此处通过配置(babel.config.js)使用core-js @ 3

最后,还有一些Github问题,涉及在您的vuex商店中执行的其他第三方库的polyfills + Promises。将所有这三个库(axios,vue-axios,vuex)添加到您的transpileDependencies部分。如果可以解决,请开始删除依赖项以查看是否需要它们。


不幸的是,所有您的建议都尝试了相同的结果:(
J.Kirk。

奇怪的。第三方插件最终会删除Promise。
杰西

对不起,我迟到了。我如何知道第三方插件是否删除了它?
J.Kirk。

0

尝试将包含.browserslistrc以下内容的文件添加到项目根目录:

> 1%
last 2 versions

请参阅有关配置的https://github.com/browserslist/browserslist#best-practices信息last versions


如果这不能解决丢失的多边形填充的问题,请尝试禁用正在使用的插件,该插件会限制块的数量,以确保这不会导致任何多边形填充的遗漏。

plugins: [
  new webpack.optimize.LimitChunkCountPlugin({
    maxChunks: 6,
  }),
],

我已经有了带有您列出的版本的browserslistrc。刚刚在没有插件的情况下进行了测试-无效:(
J.Kirk。

我的babel插件文件只有:module.exports = {预设:['@ vue / cli-plugin-babel / preset']}
Marc

和您的promise.finally在边缘工作?您有任何可能共享您的软件包列表和配置,以便我可以尝试推断出哪个软件包导致了问题吗?
J.Kirk。

我总是使用cli.vuejs.org/guide/creating-a-project.html#vue-create创建项目,但是Edge 18+支持finally()不需要填充,仅适用于Internet Explorer?
Marc

您正在使用的ApiService可能会引发您的问题,它可能不是返回本地Promise,而是它自己创建的一个模拟。尝试使用axios直接设置相同的通话作为测试。
Marc
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.