我有一段代码,该代码使用promises API检查serviceProvider
组件中的缓冲功能是否已完成。 serviceProvider
带有一个标志,可以用getBufferingStatus()
进行轮询。
使用ensureBufferingHasFinished().then(....).catch(err => console.log(err))
时,显示无法从this.serviceProvider
访问该条件
我以前曾经使用诺言,但这是我在这种特殊情况下第一次使用诺言。如何将this.
绑定到诺言?感谢所有帮助!
ensureBufferingHasFinished() {
return new Promise(function (resolve, reject) {
(function waitForBufferingComplete(){
if (!this.serviceProvider.getBufferingStatus()) {
alert("RESOLVED");
return resolve();
}
setTimeout(waitForBufferingComplete, 250);
})();
});
}
答案 0 :(得分:2)
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
传递给您在waitForBufferingComplete
周围创建的IIFE,尽管您的代码结构只有在支持与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的平台,则该版本引入了arrow functions,它忽略了执行上下文并保留了其父级this
的词汇范围:
function ensureBufferingHasFinished() {
return new Promise((resolve, reject) => {
var waitForBufferingComplete = () => {
if (!this.serviceProvider.getBufferingStatus()) {
alert("RESOLVED");
return resolve();
}
setTimeout(waitForBufferingComplete, 250);
}
});
}
答案 1 :(得分:1)
您可以做的是在sureBufferingHasFinished的参数中传递serviceProvider实例。
n1
答案 2 :(得分:1)
将this
绑定到Promise
函数,并将serviceProvider
作为参数传递给iife。将serviceProvider
作为第三个参数传递到setTimeout
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));
}
答案 3 :(得分:1)
您的this
指向函数的内部范围。您可以使用局部变量来存储this
的引用,并在所有内部范围中使用它:
ensureBufferingHasFinished() {
let ref = this;
return new Promise(function (resolve, reject) {
(function waitForBufferingComplete(){
if (!ref.serviceProvider.getBufferingStatus()) {
alert("RESOLVED");
return resolve();
}
setTimeout(waitForBufferingComplete, 250);
})();
});
}
答案 4 :(得分:-1)
尝试一下:
waitForBufferingComplete = function(bufferingSuccess){
if (!this.serviceProvider.getBufferingStatus()) {
bufferingSuccess(true);
}
else{
setTimeout(waitForBufferingComplete, 250);
}
}
ensureBufferingHasFinished() {
return new Promise(function (resolve, reject) {
waitForBufferingComplete(function(isFinishedBuffering){
if (isFinishedBuffering){
resolve('ok');
}
});
});
}