是否可以将变量引用或指针传递到javascript中的回调函数中?

时间:2019-06-21 14:51:01

标签: javascript reference

我正在重构javascript,并且对相同的PHP网址有很多类似的POST调用。

最好将postdata和callback函数(在JiraChangeStatus中定义)传递给通用函数(SendPost)。

我是javascript新手,给人的印象是,如果变量是对象的属性,则可以使用指针/引用。

还尝试使用变量“ xhr”而不是对象属性,在JiraChangeStatus中声明“ xhr”而不是SendPost,甚至在全局中将其声明为健全性检查。

function JiraChangeStatus(index) { 

    var postdata = "&status="+document.getElementById("jiraT"+(index).toString()).value;

    SendPost("changestatus.php",postdata, function(obj) {
        alert("readyState: "+obj.xhr.readyState+"\r\nstatus: "+obj.xhr.status);                            
    });                                                  
}

function SendPost(module,postdata,fn)
{
    var obj = {xhr: new XMLHttpRequest()}
    var issuekey = GetJson(document.getElementById("issue").value,'key');                                              
    obj.xhr.open("POST", "modules/jira/"+module, true);
    obj.xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    obj.xhr.onreadystatechange = fn(obj);
    obj.xhr.send("username=user&issuekey="+issuekey+postdata);  
}

当执行回调函数时,我总是看到readystate 1和status0。我希望看到4和200。

看来javascript正在将xhr对象的副本传递给回调而不是实际对象。

这些功能在合并时有效。除非在“ xhr”的回调函数的范围内设置“ xhr”的属性,否则回调不会获取该值。

请让我知道我在做错什么。

1 个答案:

答案 0 :(得分:0)

感谢Pointy和Bergi。

在解决用户故事时,代码存在两个问题。

首先是,当我使用obj.xhr.onreadystatechange = fn(obj)时,它立即评估了fn。即时评估导致“ this”具有鼠标单击作为事件触发器,而不是onreadystatechange。

第二个是冗余。当“ this”引用xhr时,无需将xhr作为参数传递。

此代码不起作用(忽略了不相关的行):

function JiraChangeStatus(index) { 
    SendPost("changestatus.php",postdata, function(pass) {
        console.log("This:\r\n"+this); //This: [object Window]                                 
    });                                                  
}
function SendPost(module,postdata,fn) {  
    var xhr = new XMLHttpRequest();     
    xhr.onreadystatechange = fn();       
}

此代码可以正常工作(忽略不相关的行):

function JiraChangeStatus(index) { 
    SendPost("changestatus.php",postdata, function(pass) {
        console.log("This:\r\n"+this); //This: [object XMLHttpRequest]                                 
    });                                                  
}
function SendPost(module,postdata,fn) {  
    var xhr = new XMLHttpRequest();     
    xhr.onreadystatechange = fn;   //no parentheses here fixed my use case    
}

因此,当他们解决我的用例时,我会接受Pointy和Bergi的评论。

但是,我发布的问题是关于将引用传递给回调函数,我想向在搜索中找到它的人们提供有用的信息。

我的问题的答案是:How can I pass a parameter to a function without it running right away?

:当括号引起立即求值时如何传递对回调的引用

为了验证它在我的用例中是否“有效”,我编写了一些非常丑陋和不必要的代码,该代码表明您可以通过直接使参数返回一个函数来将参数传递给带有括号的回调函数。

由于JavaScript允许通过引用分配对象,而“ xhr”是一个对象,正如Bergi所说,我不需要对象包装器(省略了不相关的行):

function SendPost(module,postdata,fn)
{         
    var xhr = new XMLHttpRequest();      
    xhr.onreadystatechange = fn(xhr); //immediately evaluates fn
}
function JiraChangeStatus(index) { 
    SendPost("changestatus.php",postdata, function(pass) {
        //the result of immediate evaluation is a function 
        //with the parameter "pass" in its scope
        return function() {
            console.log("This:\r\n"+this); //This: [object XMLHttpRequest]
            console.log(this.responseText); //returns the expected response text                
            console.log("Passed Reference:\r\n"+pass); //Passed Parameter: [object XMLHttpRequest]
            console.log(pass.responseText);
            //Both of these stop future callbacks
            //this.abort();
            //pass.abort();
        }
    });                                                  
}