Chrome正常运行的Promise代码在IE11中报错:'Promise'未定义
解决IE11中
ReferenceError: 'Promise' is undefined的问题 这个问题根源很清晰:IE11完全不支持ES6原生的Promise对象,而你的代码里直接使用了new Promise(...)和Promise.all(),这就是报错的核心原因。好在你的Angular项目已经注入了$q服务——Angular官方的Promise实现,完全可以用它来替代原生Promise,不用额外引入第三方依赖,完美适配IE11环境。
下面是针对你代码的具体修改方案:
1. 替换getContentTypeOfCurrentItem中的原生Promise
把这个函数里的原生Promise逻辑,换成Angular的$q.defer()实现:
function getContentTypeOfCurrentItem(id) { var deferred = $q.defer(); // 用Angular的$q创建延迟对象 var clientContext = new SP.ClientContext.get_current(); var oList = clientContext.get_web().get_lists().getByTitle("Bill Cycles"); var listItem2 = oList.getItemById(id); listContentTypes = oList.get_contentTypes(); clientContext.load(listContentTypes); clientContext.load(listItem2, 'ContentTypeId'); clientContext.executeQueryAsync( function() { $log.info("Successfully retrieved getContentTypeOfCurrentItem"); var ctid = listItem2.get_item("ContentTypeId").toString(); var ct_enumerator = listContentTypes.getEnumerator(); var contentTypeName; while (ct_enumerator.moveNext()) { var ct = ct_enumerator.get_current(); if (ct.get_id().toString() == ctid) { contentTypeName = ct.get_name(); break; // 找到匹配项后直接跳出循环,优化性能 } } deferred.resolve(contentTypeName); // 用deferred对象触发成功回调 }, function(error, errorInfo) { $log.warn("Retrieving getContentTypeOfCurrentItem failed"); deferred.reject(errorInfo); // 用deferred对象触发失败回调 } ); return deferred.promise; // 返回$q封装的promise对象 }
2. 替换GetRelatedBillingDocumentsFromList中的Promise.all
把原生的Promise.all(promises)换成Angular的$q.all(promises):
// 原代码:Promise.all(promises).then(youCanUseTheData); $q.all(promises).then(youCanUseTheData); // 使用$q.all处理多个异步任务
备选方案:引入Promise Polyfill(如果不想修改代码)
如果不想改动现有Promise相关代码,也可以给IE11补全Promise的实现,比如引入es6-promise polyfill:
- 安装依赖:
npm install es6-promise --save - 在项目入口文件(比如
app.js)中全局引入:
import 'es6-promise/auto';
不过相比之下,用项目已有的$q服务更轻量,不需要额外增加依赖包。
验证修改
完成修改后重新在IE11中测试,ReferenceError: 'Promise' is undefined的报错应该会完全消失——因为现在代码使用的是Angular兼容IE11的$q异步实现,而非原生ES6 Promise。
内容的提问来源于stack exchange,提问作者Luis Valencia




