【问题标题】:Javascript, variable is not getting assigned... why?Javascript,变量没有被分配......为什么?
【发布时间】:2011-08-25 03:25:10
【问题描述】:

这是我最简单的代码:

var this_version =null;

this.timervar = setTimeout(function () {
    try {
        // Firefox 4 and later; Mozilla 2 and later
        Components.utils.import("resource://gre/modules/AddonManager.jsm");
        AddonManager.getAddonByID("parasites@maafire.com", function(addon) {
            this_version = addon.version;
            alert("r "+this_version);
        });
    } catch (ex) {
        // Firefox 3.6 and before; Mozilla 1.9.2 and before
        var em = Components.classes["@mozilla.org/extensions/manager;1"]
            .getService(Components.interfaces.nsIExtensionManager);
        var addon = em.getItemForID("parasites@maafire.com");
        this_version = addon.version;
        alert("rr " + this_version);
    }
    alert("rrr " + this_version);
}, 2000);

这太奇怪了,因为它会触发两次alert("r "+this_version);,但是这个alert("rrr "+this_version);总是给我null ;(

还在学习 JS ,所以这很令人费解......请帮助!

谢谢!

【问题讨论】:

  • 当你的代码被这样格式化时,没有人会费心查看你的代码
  • 那么单 r 会引起什么警报?三个 r 的警报是否发生在单个 r 的警报之前?
  • 首先我得到r 0.5 然后rrr null 然后r 0.5 然后rrr null

标签: javascript variable-assignment


【解决方案1】:

设置this_version 变量的代码位于回调中,因此对变量的更改不会反映在第三个alert 执行的范围内。

【讨论】:

  • 那么,如何将该值放入我的变量中,以便在其他地方使用它?
  • 这不是范围问题,而是时间问题。鉴于代码在全局上下文中运行,所有函数都在访问相同的 this_version 变量。即使外部上下文是函数代码,它们也会对同一个实例有一个闭包,因为它们的作用域链上没有其他 this_version。问题是赋予 setTimeout 的函数在其他函数设置值之前运行,因此在它运行时,尚未调用设置值的函数。
  • @Ryan - 大概 Components 正在发出异步 AJAX 请求(因此存在时间问题)。您可以通过使调用同步来解决此问题,但这可能不是您想要的。
  • 由于这是异步运行的,我认为这是一个时间问题,这就是为什么我将其置于 settimeout 中...希望这 2 秒足以让它获得所需的内容并更新主要变量我可以在其他地方使用……但是那不起作用,那你建议我怎么做呢?
  • 使用 setTimeout 调用 Components 只会延迟一切。您可以尝试使用 setInterval 进行轮询(丑陋,因为 XHR 可能永远不会成功完成,因此不会设置变量)。您可能需要一个控制器函数,该函数在进行 XHR 调用时被告知,以便控制器设置一个标志(对象属性等)。让回调告诉它何时完成,以便清除标志。当每个返回时,控制器检查是否有任何需要清除。如果它们都完成了,它会继续处理。
【解决方案2】:

这是在 JavaScript 世界中正确的做法:

function done() {
    alert("rrr "+this_version);
}

var this_version =null;
try {
    // Firefox 4 and later; Mozilla 2 and later
    Components.utils.import("resource://gre/modules/AddonManager.jsm");
    AddonManager.getAddonByID("parasites@maafire.com", function(addon) {
        this_version = addon.version;
        alert("r "+this_version);
        done();
    });
} catch (ex) {
    // Firefox 3.6 and before; Mozilla 1.9.2 and before
    var em = Components.classes["@mozilla.org/extensions/manager;1"]
        .getService(Components.interfaces.nsIExtensionManager);
    var addon = em.getItemForID("parasites@maafire.com");
    this_version = addon.version;
    alert("rr " + this_version);
    done();
}

甚至更好:

function done(version) {
    alert("rrr "+version);
}

然后这样称呼它:

done(this_version);

【讨论】:

    【解决方案3】:

    好的,只需将除警报之外的所有内容移出计时器即可解决:

    var this_version =null;
    try {
        // Firefox 4 and later; Mozilla 2 and later
        Components.utils.import("resource://gre/modules/AddonManager.jsm");
        AddonManager.getAddonByID("parasites@maafire.com", function(addon) {
            this_version = addon.version;
            alert("r "+this_version);
        });
    } catch (ex) {
        // Firefox 3.6 and before; Mozilla 1.9.2 and before
        var em = Components.classes["@mozilla.org/extensions/manager;1"]
            .getService(Components.interfaces.nsIExtensionManager);
        var addon = em.getItemForID("parasites@maafire.com");
        this_version = addon.version;
        alert("rr " + this_version);
    }
    
    this.timervar = setTimeout(function ()
                                { 
    
    
    
                                        alert("rrr "+this_version);
    
    
                                }, 2000);
    

    【讨论】:

    • 这不是一个可靠的解决方案。等待 2 秒并不能保证 this_version 已设置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多