0

まず、関連する SO の質問を調べましたが、適切な回答の方法があまり見つかりませんでした。

バックエンド サーバーの UI として機能する HTML/Javascript ページに取り組んできました。AJAX (別名 ) で同期呼び出しを使用している間、私はそれを完了するのにかなりの進歩を遂げましたvar xmlhttp = new XMLHttpRequest(); xmlhttp.open(type, action, false);が、Mozilla が明らかに同期要求を好まないことがわかりました。

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequestを引用するには:

注: Gecko 11.0 (Firefox 11.0 / Thunderbird 11.0 / SeaMonkey 2.8) および WebKit ビルド 528 以降、これらのブラウザーでは、同期要求を実行するときに responseType 属性を使用できなくなりました。そうしようとすると、NS_ERROR_DOM_INVALID_ACCESS_ERR 例外がスローされます。この変更は、標準化のために W3C に提案されています。

それは素晴らしいことです。条件付きで応答タイプを変更する必要がありますが、機能しません。同期性をシミュレートする何かでAJAX 非同期要求をラップすることが私の意図です。

以下は、私のコードが使用する一般的な「Web リクエストの作成」関数であり、目的に合わせて動作するように適応し始めています。残念ながら、私が望んでいたようには機能していません。

var webResponse = null;

function webCall(action, type, xmlBodyString) {
console.log("In webCall with " + type + ": " + action);
webResponse = null;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
    if (xmlhttp.readyState == 4)
    {
        if (xmlhttp.status == 200) {
            webResponse = xmlhttp.responseXML;
        } else {
            var statusTxt = xmlhttp.statusText;
            if (statusTxt == null || statusTxt.length == 0) {
                statusTxt = "An Unknown Error Occurred";
            }
            throw "ERROR " + xmlhttp.status + ":" + statusTxt;
        }
    }
}
xmlhttp.open(type, action, true);
if (xmlBodyString == null) {
    xmlhttp.send();
} else {
    xmlhttp.setRequestHeader("Content-Type", "text/xml");
    xmlhttp.send(xmlBodyString);
}

for (var i = 0; i < 20; i++) {
    if (webResponse != null) {
        break;
    }
    window.setTimeout(nop, 250);
}
if (webResponse == null) {
    throw "Waited 5 seconds for a response, and didn't get one.";
}
console.log("Responding with " + webResponse);
return webResponse;
}

function nop() {
}

だから、これはかなり簡単だと思いました。グローバル変数を作成し(振り返ってみると、おそらくグローバルである必要さえありませんが、今のところはw / e)、onreadystatechangeを設定して、準備ができたら値を割り当て、非同期リクエストを作成し、最大待機しますグローバル変数が null ではないために 5 秒かかり、それを返すか、エラーをスローします。

問題は、私のコードが実際には 5 秒待たないことです。代わりに、5 秒待ってから終了したと主張して、すぐに終了します。

価値があるので、私はフィドルを作りました。そこでもうまくいきません。 http://jsfiddle.net/Z29M5/

どんな援助も大歓迎です。

4

3 に答える 3

2

あなたはそれをすることはできません。非同期リクエストに固執します。コールバック地獄はひどいものですが、それは言語サポートのないイベント駆動型システムで得られるものです。

現時点では、ブラウザーでプレーンな JavaScript で同期コードをシミュレートする方法はまったくありません。

サポートされているブラウザーのセットを厳しく制限できる場合 (現時点ではほとんど Firefox のみ)、ジェネレーターを使用して同期のようなコードを取得できます

JS にコンパイルされ、同期のように見えるコードをサポートする言語もあります。私が考えることができる1つの例(数年前から)はこれです:https://github.com/maxtaco/tamejs

于 2013-10-09T00:16:39.520 に答える
1

まず、すべての苦痛に対して、非同期コードを非同期で使用することが最善の方法です。それは別のアプローチをとります、それだけです。

第二に、あなたの特定の質問について、これはあなたの「遅延」ループが行っていることです:

For twenty iterations
  if we've had a response, break
  set a timeout for 250ms
go round again

(for ループ全体が 20 回の反復すべてをすぐに完了します。応答はありません)

. . . 250ms後

setTimeout最初のコールバックを実行します。nop

2番目を実行...

処理コードをAJAXコールバックに配置する以外に、これを修正する簡単な方法は考えられません。これは、とにかく非同期コードの場合にあるべき場所です。

于 2013-10-09T00:24:25.927 に答える
0

リクエストの配列を作成して、前の ajax 呼び出しからの応答を取得したら、それらを 1 つずつポップしてみませんか。

于 2013-10-09T00:40:59.180 に答える