向ES6添加Promise兼容性库

17

我有一个使用ES6编写的React项目。它通过Babel编译并且运行得很好。除了一个Promise(其中之一!)只会在IE中出现问题,这已经知道-不支持Promise。所以我立即想到添加一个Polyfill来为IE提供Promise,但是我突然想到“等等,你已经写ES6了,那不是已经编译成ES5了吗?”谁比SO更了解呢?
因此,在我的项目中添加es6-promise等Polyfill是否有意义?如果有必要,语法上应该如何使用它?目前我只有导入,但我应该以某种方式实现它吗?

import Promise from 'es6-promise';

这里还有一个承诺在IE中会引起问题,也许我有一个语法错误,但是我自己没有注意到!:)

new SingleObjectResource(DJ_CONST.API.setLanguage)
    .put(null, {language_code: theLanguage})
    .then(
        function() {
            window.location.reload();
        }
    );

8
Babel只将语言特性转译为ES5。你仍然需要polyfills :) 将其放在页面顶部即可,不需要担心导入任何内容,只需像本地可用一样编写ES6代码。 - CodingIntrigue
1
据我所知,es6-promise是一个缓慢而相当过时的polyfill。 - Benjamin Gruenbaum
RGraham,我会在第一时间尝试它,但似乎你已经在只用两句话的情况下捕捉到了我期望的答案。谢谢! - wanaryytel
1
为什么不在任何地方都使用bluebird呢?它比本地的promises更快(https://github.com/petkaantonov/bluebird/tree/master/benchmark)。而且还有[IE的polyfills](https://github.com/este/este/issues/599)。我并不为他们工作 :)。 - hazardous
SingleObjectResource 是你自己写的还是第三方库?控制台有没有报错?如果没有,尝试在 .then() 后添加 .catch(function (error) { console.log(error); }) - JLRishe
SingleObjectResource是一个库的一部分。现在我已经将babel-polyfill添加到我的项目中,但IE仍然无法正常工作,并且在IE控制台中收到了“未处理的Promise拒绝错误”。不知道在添加babel之前是否存在该问题。它只是在等待一段时间后才出现,而不是立即出现。无论如何 - 我应该在包含SingleObjectResource的文件中导入polyfill还是在调用包含SingleObjectResource的函数的文件中导入? - wanaryytel
3个回答

13

我遇到了同样的问题,因为我需要部署生产应用程序而非常沮丧,我遇到的问题是来自fetchjs的Promise。以下是我所做的操作,让我保命:

npm install --save es6-promise //first install as a dependency & then added in broswerify as dependency.

然后在我的主要JS文件中,只需调用这个

   import "es6-promise/auto";

从这里开始:https://github.com/stefanpenner/es6-promise#auto-polyfill

基本上,它是替代语法的。

require('es6-promise').polyfill();

基本上,在幕后,polyfill() 方法在被调用时将会修补全局环境(在本例中,是 Promise 名称)。

注意:我正在使用 gulp 和 browserify。


1

我之前无法编辑我的回复,因为我在晚上收到评论时不在线...根据评论反馈重新发布我的回复,并嵌入信息。谢谢。

为什么不在所有地方使用 bluebird ?它比原生承诺更 。并支持IE的polyfills。而且我不是他们的员工 :)

编辑:

使用 bluebird 而不是原生的 promise -

const Promise = require('bluebird');

1. 添加性能比较 -

results for 10000 parallel executions, 1 ms per I/O op

file                                     time(ms)  memory(MB)
callbacks-baseline.js                         232       35.86
promises-bluebird-generator.js                235       38.04
promises-bluebird.js                          335       52.08
promises-cujojs-when.js                       405       75.77
promises-tildeio-rsvp.js                      468       87.56
promises-dfilatov-vow.js                      578      125.98
callbacks-caolan-async-waterfall.js           634       88.64
promises-lvivski-davy.js                      653      109.64
promises-calvinmetcalf-lie.js                 732      165.41
promises-obvious-kew.js                      1346      261.69
promises-ecmascript6-native.js               1348      189.29
generators-tj-co.js                          1419      164.03
promises-then-promise.js                     1571      294.45
promises-medikoo-deferred.js                 2091      262.18
observables-Reactive-Extensions-RxJS.js      3201      356.76
observables-caolan-highland.js               7429      616.78
promises-kriskowal-q.js                      9952      694.23
observables-baconjs-bacon.js.js             25805      885.55

Platform info:
Windows_NT 6.1.7601 x64
Node.JS 1.1.0
V8 4.1.0.14
Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz × 4

2. IE Polyfill 代码 -
import Bluebird from 'bluebird';
// Node
global.Promise = Bluebird;
// Browser
window.Promise = Bluebird;

这仍然没有回答问题,你用“使用jQuery”来回答“如何选择元素”的问题。性能基准与手头的问题完全无关。 - Madara's Ghost
1
你的比较是可以理解的,但我不同意我的评论与手头的话题无关。OP提出了一个可能在IE上存在Promise跨浏览器问题,并且正在评估使用另一个已被证明比bluebird慢的polyfill。我提到的替代方案不仅比本地更快,而且还支持IE。类似于你的例子的论点是...使用jQuery而不是querySelector,因为后者尚未被所有浏览器支持。 - hazardous
性能问题与此问题无关,浏览器兼容性才是关键。 - Madara's Ghost
似乎与本题相关,正如Benjamin所提到的,es6 polyfill速度较慢是一个重要因素。OP明确要求推荐使用它。无论如何,我会让OP自己决定。 - hazardous
速度确实是一个有效的观点,但如果我成功使用babel,我更喜欢不包括另一个库的解决方案(因为我已经在运行babel)。当然,如果我像一开始计划的那样运行es6-promise,那么你的帖子就会更有相关性,因为es6-promise也是一个单独的库。但是你最初的帖子肯定没有说明如何精确地实现bluebird,它只是指出它可以很好地替代es6-promise - 我认为这个评论更合适。 - wanaryytel
我没想到如何使用 bluebird 需要解释。大多数情况下,它是这样的 -const Promise = require('bluebird'); - hazardous

1
尽管您正在使用Babel(仅进行转译而不添加功能),但需要使用polyfills。
您需要做的就是安装该软件包:
npm install --save es6-promise

webpack.config.js 中(或者你的 webpack 配置文件所在的任何地方,假设你正在使用 webpack)

require('es6-promise').polyfill();

当调用polyfill()方法时,它将修补全局环境(在本例中为Promise名称)。更多信息请参见https://github.com/stefanpenner/es6-promise


2
你如何将 "require('es6-promise').polyfill();" 写成 ES6 的 import 语句? - williamwmy
你可以尝试使用 "import" 符号。我也有一个 ES6 项目,但我仍然将这行代码编写为 ES5。 - tomericco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接