2

コードは同期的ではないため、コードに多くの問題があります。これは、クロム拡張機能で発生した問題の例です。これが私の機能です

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

chrome.storageajax の代わりに同期 XHR を使用しているため、非同期であるの代わりに同期関数を使用してデータを保存する必要があります。

chrome.storageのドキュメントでは、その機能の 1 つが

  • 一括読み取りおよび書き込み操作とは非同期であるため、ブロッキングおよびシリアルlocalStorageAPI よりも高速です。

しかし、ブロック (および同期) したいのであれば、代わりにその API に変更してみませんか?

またはさらに良い:

getTranslation()関数を非同期に変換します。コールバックとなる 3 番目のパラメーターを追加し、それをネストされたコールバック内で使用するだけで済みます (これを行うと、同期 XHR の代わりに ajax を使用することもできるため)。

その方法は正しいことですが、怠惰で簡単な方法が必要な場合は、前者を実行して に変更chrome.storageするlocalStorageだけで完了です。

編集:機能を非同期に変更したことがわかります。正しく動作しているようですが、質問を更新しましたが、この行が機能しない理由を理解するのに問題があるようです:

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

イベント指向プログラミングがどのように機能するかを理解する必要があります。あなたはラインと思うかもしれません

for (counter in toTranslateArray)

これは、 「この toTranslateArray 内のすべてのカウンターを変換する」ことgetTranslationを意味しますが、実際には「この toTranslateArray 内のすべてのカウンターに対して変換イベントを発生させる」ことを意味します。

つまり、それconsole.logが実行されると、このタスクは起動されたばかりです。完了するのを待ちません。したがって、その瞬間に翻訳されたものは空です。そしてそれは正常で、非同期で実行されます。

var が終了したら何をする必要があるのか​​ わかりませんがtranslated、配列の最後の項目が処理されたら、別のイベントを発生させようとします。

とにかく、必要なことは、イベント指向プログラミングに関するチュートリアルか何かを勉強することです。

についてはlocalStorage、わかりません。ドキュメントの代替としてそれについてchrome.storage知りましたが、あなたの場合にそれを使用する方法が本当にわかりません。

しかし、javascript はイベント指向であるため、単に同期に戻るのではなく、イベントを学習することを強くお勧めします。しかし、あなた次第です。

于 2013-08-13T17:29:48.863 に答える
0

カスタム イベント リスナーを作成します。json_data の文字列化が完了したら (提案されているようにコール バック内で実行)、イベントを発生させて ajax 呼び出しを実行します。カスタム イベント JavaScript カスタム イベント リスナーの詳細については、こちらを参照してください。

于 2013-08-13T16:33:57.960 に答える