简体   繁体   English

JSONP回调和闭包/范围

[英]JSONP Callbacks and Closures/Scope

I am using the Microsoft Translation api (AJAX Version) from http://www.microsofttranslator.com/dev/ 我正在使用http://www.microsofttranslator.com/dev/上的Microsoft Translation api(AJAX版本)

I am having some issues with closures and callbacks, which I hope this code will demonstrate: 我有一些关闭和回调的问题,我希望这段代码能够证明:

function translate(original){

    window.translateComplete = function(language) {

        if (language!="en"){
        alert(original +" "+language);
        }   
    }


    var windowsliveid = 'API_KEY_REMOVED';
    var el = document.createElement("script"); 
    el.src = 'http://api.microsofttranslator.com/V2/Ajax.svc/Detect'; 
    el.src += '?oncomplete=translateComplete'; 
    el.src += '&appId=' + windowsliveid; 
    el.src += '&text=' + escape (original); 
    document.getElementsByTagName('head')[0].appendChild (el);

}

translate("Au Revoir"); 
translate("Hola"); 

Now, my response comes back as 现在,我的回复又回来了

Hola es
Hola fr

The original variable is being overwritten, before the callback has had a chance to execute. 在回调有机会执行之前, original变量被覆盖。

How do I avoid this so that it displays something like: 如何避免这种情况,以便显示如下内容:

Hola es
Au revoir fr

I am trying to do this without using jQuery and when() 我试图这样做而不使用jQuery和when()

Thanks 谢谢

Well, you are using the same callback function for every response, since window. translateComplete 好吧,从window. translateComplete ,每个响应都使用相同的回调函数window. translateComplete window. translateComplete can only refer to one function. window. translateComplete只能引用一个函数。 So every call to translate will overwrite window.translateComplete with a new function, which is a closure. 因此,每次调用translate都会使用一个新函数覆盖window.translateComplete ,这是一个闭包。

You could create a new callback with a different name for each call. 您可以为每个调用创建一个具有不同名称的新回调。 That's what jQuery is doing. 这就是jQuery正在做的事情。

In it's simplest form: 以它最简单的形式:

var i = 0; // some running variable
function translate(original){

    var cb_name = 'cb' + (i++); // create a new name
    window[cb_name]= function(language) {
        delete window[cb_name]; // remove function to not pollute the global scope
        if (language!="en"){
            alert(original +" "+language);
        }   
    }

    var windowsliveid = 'API_KEY_REMOVED';
    var el = document.createElement("script"); 
    el.src = 'http://api.microsofttranslator.com/V2/Ajax.svc/Detect'; 
    el.src += '?oncomplete=' + cb_name; // use the dynamic name instead
    el.src += '&appId=' + windowsliveid; 
    el.src += '&text=' + escape (original); 
    document.getElementsByTagName('head')[0].appendChild (el);
}

It's because you're re-assigning the global "translateComplete" function when you call "translate". 这是因为当您调用“translate”时,您将重新分配全局“translateComplete”函数。 There can only be one function bound to that single property of "window", right? 只有一个函数绑定到“窗口”的单个属性,对吗?

(The "original" variable is not being changed; it's just that the first function, with "Au Revoir", is cast off completely to float around aimlessly while waiting to be garbage collected.) (“原始”变量没有被改变;只是第一个功能,“Au Revoir”,被完全抛弃,在等待被垃圾收集时无目的地漂浮。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM