web-dev-qa-db-ja.com

XHR.onreadystatechangeに結果を返すようにするにはどうすればよいですか?

私はJavaScriptプログラミングに不慣れです。私は今Googleで作業していますChrome拡張機能。これは機能しないコードです...:P

getURLInfo関数でJSONオブジェクトを返し、それをrespに入れたいと思います。誰かが私のコードを修正して動作させることができますか?

function getURLInfo(url)
{
    var xhr = new XMLHttpRequest();
    xhr.open
        (
            "GET",
            "http://RESTfulAPI/info.json?url="
                + escape(url),
            true
        );
    xhr.send();
    xhr.onreadystatechange = function()
    {
        if (xhr.readyState == 4)
        {
            return JSON.parse(xhr.responseText);
        }
    }
}
var resp = getURLInfo("http://example.com/") // resp always returns undefined...

前もって感謝します。

16
Japboy

ここでは非同期関数呼び出しを扱っています。結果は、関数の実行が終了したときではなく、到着したときに処理されます。

それがコールバック関数の目的です。結果が利用可能になると呼び出されます。

_function get(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            // defensive check
            if (typeof callback === "function") {
                // apply() sets the meaning of "this" in the callback
                callback.apply(xhr);
            }
        }
    };
    xhr.send();
}
// ----------------------------------------------------------------------------


var param = "http://example.com/";                  /* do NOT use escape() */
var finalUrl = "http://RESTfulAPI/info.json?url=" + encodeURIComponent(param);

// get() completes immediately...
get(finalUrl,
    // ...however, this callback is invoked AFTER the response arrives
    function () {
        // "this" is the XHR object here!
        var resp  = JSON.parse(this.responseText);

        // now do something with resp
        alert(resp);
    }
);
_

ノート:

  • escape()は永久に非推奨になりました。使用しないでください。正しく動作しません。 encodeURIComponent()を使用します。
  • couldsend()asyncパラメータをfalseに設定することにより、open()呼び出しを同期させます。これにより、リクエストの実行中にUIがフリーズすることになりますが、これは望ましくありません。
  • Ajaxリクエストを簡単で用途の広いものにするように設計されたライブラリはたくさんあります。そのうちの1つを使用することをお勧めします。
24
Tomalak

非同期XHR呼び出しではまったく実行できません。 JavaScriptをサーバーからのHTTP応答を「待機」させることはできません。あなたができることは、ランタイムシステムに呼び出す関数(ハンドラー)を渡すことだけで、それを呼び出します。ただし、その呼び出しは、XHRを設定したコードが終了した後に長い時間になります。

ただし、そのハンドラー関数はanythingを実行できるため、すべてが失われるわけではありません。戻り値でやりたいことが何であれ、実行できます内部ハンドラー(またはハンドラーの内部から呼び出される他の関数から)。

したがって、あなたの例では、次のように変更します。

    xhr.onreadystatechange = function()
    {
        if (xhr.readyState == 4)
        {
            var resp = JSON.parse(xhr.responseText);
            //
            // ... whatever you need to do with "resp" ...
            //
        }
    }
}
3
Pointy