最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

对象的方法可以在函数调用函数调用时对自己,但是当通过的setTimeout调用的函数的对象是不确定的

运维笔记admin10浏览0评论

对象的方法可以在函数调用函数调用时对自己,但是当通过的setTimeout调用的函数的对象是不确定的

对象的方法可以在函数调用函数调用时对自己,但是当通过的setTimeout调用的函数的对象是不确定的

我有以下类Conference

//UrlSerializer is for encoding JSON objects into GET url
const UrlSerializer=require('./urlSerializer');

class Conference{

    constructor(client,workspace){
        this.client=client;
        this.workspace=workspace;
        this.urlSerializer=new UrlSerializer();
    }


    announce(conferenceSid,timeRemaining){
        var parameters={
            timeRemaining:timeRemaining
        }
        var url=this.urlSerializer.serialize('conferenceAnnounceTime',parameters);
        console.log("conference.announce url: "+url);
        this.client.conferences(conferenceSid)
            .update({
                announceUrl:url,
                announceMethod:'GET'
            })
            .then(conference=>console.log(conference.friendlyName));
    }

    setTimedAnnounce(initialMinutes,minutesToElapse,conferenceSid){
        var minutesRemaining=initialMinutes-minutesToElapse;
        setTimeout(this.announce,minutesToElapse*60000,minutesRemaining);
    }

}

module.exports=Conference;

UrlSerializer是:

const querystring=require('querystring');
require('env2')('.env');

class UrlSerializer{

    constructor(){
        this.paramArrayName="parameters";
    }

    serialize(endpoint,paramArray){
        var url=process.env.APP_BASE_URL+"/"+endpoint;
        console.log("urlSerializer base url: "+url);
        var arrayString=JSON.stringify(paramArray);
        console.log("urlSerializer stringified parameter array: "+arrayString);
        var fullUrl=url+"?"+querystring.stringify({[this.paramArrayName]:arrayString});
        console.log("urlSerializer full url: "+fullUrl);
        return fullUrl;
    }   
}

module.exports=UrlSerializer;

我打电话从不同的模块conference一个Express端点server功能,如下所示:

app.get('/conferenceEvents',function(req,res){
    conferenceSid=req.query.ConferenceSid;
    conference.announce(conferenceSid,initialMinutes);
    conference.setTimedAnnounce(initialMinutes,0.25,conferenceSid);
    res.type('application/json');
    res.status(200).send();
});

conference.announce调用成功与控制台输出:

urlSerializer base url: 
urlSerializer stringified parameter array: {"timeRemaining":5}
urlSerializer full url: =%7B%22timeRemaining%22%3A5%7D
conference.announce url: =%7B%22timeRemaining%22%3A5%7D

但是,当第15秒后调用conference.setTimedAnnounce()后,我收到以下错误:

TypeError: Cannot read property 'serialize' of undefined
    at Timeout.announce [as _onTimeout] (c:\thisAppPath\conference.js:45:30)
    at ontimeout (timers.js:502:15)
    at tryOnTimeout (timers.js:323:5)
    at Timer.listOnTimeout (timers.js:290:5)

我想,也许当计时器调用announce,它这样做的方式,在urlSerializer实例超出范围。我如何让它认识urlSerializerannounce通过setTimeout()叫什么名字?

编辑:我试图保存this范围如下:

    setTimedAnnounce(initialMinutes,minutesToElapse,conferenceSid){
        var that=this;
        var minutesRemaining=initialMinutes-minutesToElapse;
        setTimeout(that.announce,minutesToElapse*60000,minutesRemaining);
    }

但只是给了我同样的错误。

编辑2:

我用Barmar的this.announce.bind(this)解决办法,解决了TypeError,但参数数组和URL未在公布的setTimeout()调用被正确构建;控制台输出如下:

urlSerializer base url: 
urlSerializer stringified parameter array: {}
urlSerializer full url: =%7B%7D
conference.announce url: =%7B%7D

我怀疑还有别的地方,我需要使用.bind(this)使urlSerializer.serialize()将调用在适当的范围内this,但我还没有跟踪它呢。

编辑3:

没关系,我理解了它 - setTimeout需要有conferenceSid传递作为参数以及minutesRemaining。现在的工作。

回答如下:
    setTimeout(this.announce,minutesToElapse*60000,minutesRemaining);

需要是

    setTimeout(this.announce.bind(this),minutesToElapse*60000,minutesRemaining);

传递函数特性作为参数不绑定this上下文。当你调用与语法的方法,它是唯一的自动绑定。

发布评论

评论列表(0)

  1. 暂无评论