javascript - 承诺抛出错误,因为它无法访问它
问题描述
我有这段代码使用 Promise API 来检查我的serviceProvider
组件的缓冲功能是否已完成。有serviceProvider
一个标志,可以用 进行轮询getBufferingStatus()
。
使用时ensureBufferingHasFinished().then(....).catch(err => console.log(err))
,它告诉我无法访问条件this.serviceProvider
我以前使用过 Promise,但这是我第一次在这种特殊情况下使用 Promise。我怎样才能this.
遵守承诺?非常感谢所有帮助!
ensureBufferingHasFinished() {
return new Promise(function (resolve, reject) {
(function waitForBufferingComplete(){
if (!this.serviceProvider.getBufferingStatus()) {
alert("RESOLVED");
return resolve();
}
setTimeout(waitForBufferingComplete, 250);
})();
});
}
解决方案
对于this
不熟悉 JavaScript 如何分配其值的细微差别的人来说,关键字是一个令人头疼的问题。的值this
对应于执行上下文,而不是作用域。在这种情况下,waitForBufferingComplete
的执行上下文与ensureBufferingHasFinished
调用上下文不同。
对于如何确保访问所需内容,您有几个选择。
将变量分配给外部范围
this
在像您这样的函数相互嵌套的情况下,分配或其属性的古老技巧是快速且可靠的:
function ensureBufferingHasFinished() {
var that = this,
sp = this.serviceProvider;
return new Promise(function (resolve, reject) {
(function waitForBufferingComplete() {
//you can use "that.serviceProvider", or "sp"
if (!sp.getBufferingStatus()) {
alert("RESOLVED");
return resolve();
}
setTimeout(waitForBufferingComplete, 250);
})();
});
}
利用function.bind()
调用bind
一个函数会强制它拥有你明确给出的执行上下文作为它的参数,如果你没有或不能在包含你需要的值的范围内有你的回调,它会更有用:
function ensureBufferingHasFinished() {
return new Promise(function (resolve, reject) {
(function waitForBufferingComplete() {
if (!this.serviceProvider.getBufferingStatus()) {
alert("RESOLVED");
return resolve();
}
setTimeout(waitForBufferingComplete.bind(this), 250);
}.bind(this))();
}.bind(this));
}
或者
function ensureBufferingHasFinished() {
return new Promise(_resolveBufferingPromise.bind(this));
}
function _resolveBufferingPromise(resolve, reject) {
(function waitForBufferingComplete() {
if (!this.serviceProvider.getBufferingStatus()) {
alert("RESOLVED");
return resolve();
}
setTimeout(waitForBufferingComplete.bind(this), 250);
}.bind(this))();
}
您也可以将 传递serviceProvider
给您制作的 IIFE waitForBufferingComplete
,尽管您的代码结构只有在支持 ES5 兼容的浏览器时才应该这样做,因为在此setTimeout
之前不支持传递其他参数:
function ensureBufferingHasFinished() {
return new Promise(function (resolve, reject) {
(function waitForBufferingComplete(serviceProvider) {
if (!serviceProvider.getBufferingStatus()) {
alert("RESOLVED");
return resolve();
}
setTimeout(waitForBufferingComplete, 250, serviceProvider);
})(this.serviceProvider);
}.bind(this));
}
使用箭头函数(ES2015 或更高版本)
如果您正在为支持 ES2015 的平台进行开发,则该版本引入了箭头函数this
,它们忽略执行上下文并保留其父级的词法范围:
function ensureBufferingHasFinished() {
return new Promise((resolve, reject) => {
var waitForBufferingComplete = () => {
if (!this.serviceProvider.getBufferingStatus()) {
alert("RESOLVED");
return resolve();
}
setTimeout(waitForBufferingComplete, 250);
}
});
}
阅读有关this
MDN的更多信息。
推荐阅读
- python - 如何使用 withColumn 将整行发送到 PySpark 中的 UFD 函数
- c++ - CTest 在简单的测试设置中找不到测试
- bash - 如何解释包含十进制转义序列的字符串?
- java - Spring Boot 患者应用程序
- python - Pyinstaller 错误:ModuleNotFoundError:没有名为“ctypes”的模块
- javascript - 显示对象和数组中的名字
- sql-server - INNER JOIN 和许多 LEFT JOIN 表的 SUM 值
- google-chrome - chrome 存储同步不跨多个设备同步
- javascript - 无法比较午夜前后的时间
- swiftui - 删除 SwiftUI 视图上的动画?