首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Promise抛出错误,因为它无法访问此

Promise抛出错误,因为它无法访问此
EN

Stack Overflow用户
提问于 2018-08-07 00:30:43
回答 5查看 172关注 0票数 1

我有一段代码,它使用promises API检查来自我的serviceProvider组件的缓冲函数是否已经完成。可以使用getBufferingStatus()serviceProvider进行轮询。

在使用ensureBufferingHasFinished().then(....).catch(err => console.log(err))时,它显示无法从this.serviceProvider访问该条件

我以前使用过promises,但这是我第一次在这种特殊情况下使用promises。如何将this.绑定到promise?非常感谢大家的帮助!

代码语言:javascript
运行
复制
ensureBufferingHasFinished() {
  return new Promise(function (resolve, reject) {
    (function waitForBufferingComplete(){
        if (!this.serviceProvider.getBufferingStatus()) {
          alert("RESOLVED");
          return resolve();
        }
        setTimeout(waitForBufferingComplete, 250);
    })();
  });
}
EN

回答 5

Stack Overflow用户

发布于 2018-08-07 00:58:58

对于不熟悉JavaScript如何赋值的细微差别的人来说,this关键字是一个令人头疼的问题。this的值对应于执行上下文,而不是作用域。在这种情况下,waitForBufferingComplete的执行上下文与调用ensureBufferingHasFinished的上下文不同。

关于如何确保访问所需内容,您有几个选择。

将变量分配给外部作用域

在函数相互嵌套的情况下,分配this或其属性的古老技巧是快速可靠的:

代码语言:javascript
运行
复制
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会强制它将显式提供的执行上下文作为其参数,如果您没有或不能在包含所需值的范围内进行回调,则会更有用:

代码语言:javascript
运行
复制
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));
}

代码语言:javascript
运行
复制
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不支持传递额外的参数:

代码语言:javascript
运行
复制
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平台进行开发,那么该版本引入了arrow functions,它忽略了执行上下文,并保留了this的父级的词法范围:

代码语言:javascript
运行
复制
function ensureBufferingHasFinished() {
    return new Promise((resolve, reject) => {
        var waitForBufferingComplete = () => {
            if (!this.serviceProvider.getBufferingStatus()) {
                alert("RESOLVED");
                return resolve();
            }
            setTimeout(waitForBufferingComplete, 250);
        }
    });
}

Read up on more about this on MDN

票数 2
EN

Stack Overflow用户

发布于 2018-08-07 00:37:45

您可以做的是在ensureBufferingHasFinished的参数中传递serviceProvider实例。

代码语言:javascript
运行
复制
ensureBufferingHasFinished(serviceProvider) {
 return new Promise(function (resolve, reject) {
  (function waitForBufferingComplete(){
       if (!serviceProvider.getBufferingStatus()) {
         alert("RESOLVED");
         return resolve();
       }
       setTimeout(waitForBufferingComplete, 250);
   })();
 });
}
票数 1
EN

Stack Overflow用户

发布于 2018-08-07 00:42:43

this绑定到Promise函数,并将serviceProvider作为参数传递给Life.将serviceProvider作为第三个参数传递给setTimeout

代码语言:javascript
运行
复制
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));
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51712030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档