2

我的代码有很多问题,因为它不是同步的。这是我在 chrome 扩展中遇到的问题示例。这是我的功能

function getTranslation(a_data, callback)
{        
    var apiKey = '####'    
    var json_object = {};
    var url = '###';
    var xmlhttp;   
    var json_parsed = {};

    storage.get('data', function(items) 
    { 
        json_object = {  
            'text': a_data,
            'from' : items.data.from,
            'to' : items.data.to 
        };
        var json_data = JSON.stringify(json_object);

        if (window.XMLHttpRequest)
        {
            xmlhttp=new XMLHttpRequest();
        }
        else
        {
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }

        xmlhttp.open("POST", url, false);
        xmlhttp.setRequestHeader("Content-type","application/json");          
        xmlhttp.setRequestHeader("Authorization","##apiKey=" + apiKey);                      
        xmlhttp.setRequestHeader("X-Requested-With","XMLHttpRequest");                      
        xmlhttp.send(json_data);

        json_parsed = JSON.parse(xmlhttp.responseText);
        callback(json_parsed.translation);
    });                      
}

这就是我在另一个函数中使用 getTranslation 函数的方式:

for (counter in toTranslateArray)
{
    getTranslation(toTranslateArray[counter],function(callback)
    {
        translated += callback;
        console.log(translated); //this is second and works
    });   
}
console.log(translated); //this is first and empty
//code depending on translated

那里有什么问题吗?

4

2 回答 2

0

创建一个自定义事件侦听器,在您完成对 json_data 的字符串化(按照建议在回调中完成)之后,它将触发事件以执行 ajax 调用。转到此处了解有关 cusotm 事件JavaScript 自定义事件侦听器的更多信息

于 2013-08-13T16:33:57.960 回答
0

由于您使用的是同步XHR,而不是ajax,因此您需要使用同步函数来保存数据,而不是chrome.storage异步的。

chrome.storage文档中,它的功能之一是

  • 它与批量读写操作是异步的,因此比阻塞和串行localStorageAPI 更快。

但是阻塞(和同步)是你想要的,那么你为什么不改用那个 API 呢?

甚至更好:

将您的getTranslation()函数转换为异步的。您只需要添加第三个作为回调的参数,并在嵌套回调中使用它(因为如果这样做,您也可以使用 ajax 而不是同步 XHR)。

那样是对的,但如果你觉得懒惰,想要更简单的方法,那就做前者,然后改成chrome.storage这样localStorage,你就完成了。

编辑:我看到您已经将您的功能更改为异步。它似乎工作正常,但你更新了你的问题,你似乎无法理解为什么这条线不起作用:

console.log(translated); //this is first and empty

您需要了解面向事件的编程是如何工作的。你可能认为这条线

for (counter in toTranslateArray)

其中包含的getTranslation意思是“翻译这个 toTranslateArray 中的每个计数器”,但实际上意味着“为这个 toTranslateArray 中的每个计数器触发一个翻译事件”

这意味着当它console.log被执行时,这些任务刚刚被触发;它不会等待它完成。所以翻译在那一刻是空的。这很正常,是异步执行的。

我不知道一旦完成后您需要对translatedvar 做什么,但是一旦处理完数组的最后一项,我会尝试触发不同的事件。

但无论如何,你需要做的是学习一些教程或一些关于面向事件编程的东西,这样所有这些对你来说更有意义。

关于localStorage,我不知道,我在chrome.storage文档中发现了它作为替代方案,我真的不知道如何在您的情况下使用它。

但是由于 javascript 是面向事件的,我真的建议你学习事件而不是仅仅回到同步。但取决于你。

于 2013-08-13T17:29:48.863 回答