1289

標準の拡張ポイントを提供する JavaScript ウィジェットがあります。その一つがbeforecreate関数です。falseアイテムが作成されないように戻す必要があります。

jQuery を使用して、この関数に Ajax 呼び出しを追加しました。

beforecreate: function (node, targetNode, type, to) {
  jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),

  function (result) {
    if (result.isOk == false) 
        alert(result.message);
  });
}

しかし、ウィジェットがアイテムを作成しないようにしたいのでfalse、コールバックではなく、マザー関数に戻る必要があります。jQuery またはその他のブラウザー内 API を使用して同期 AJAX 要求を実行する方法はありますか?

4

14 に答える 14

1224

jQueryのドキュメントから:非同期オプションをfalseに指定して、同期Ajaxリクエストを取得します。その後、母関数が処理を進める前に、コールバックでデータを設定できます。

提案どおりに変更した場合、コードは次のようになります。

beforecreate: function (node, targetNode, type, to) {
    jQuery.ajax({
        url: 'http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),
        success: function (result) {
            if (result.isOk == false) alert(result.message);
        },
        async: false
    });
}
于 2008-09-25T13:30:37.290 に答える
270

を呼び出して、jQuery の Ajax セットアップを同期モードにすることができます。

jQuery.ajaxSetup({async:false});

そして、次を使用して Ajax 呼び出しを実行しますjQuery.get( ... );

その後、もう一度電源を入れるだけです

jQuery.ajaxSetup({async:true});

@Adamが提案したのと同じことがうまくいくと思いますが、自分のjQuery.get()またはjQuery.post()より複雑なjQuery.ajax()構文を再構成したい人には役立つかもしれません。

于 2011-04-12T21:45:44.857 に答える
144

優れたソリューション!実装しようとしたときに、success 句で値を返すと、未定義として返されることに気付きました。それを変数に格納して、その変数を返す必要がありました。これは私が思いついた方法です:

function getWhatever() {
  // strUrl is whatever URL you need to call
  var strUrl = "", strReturn = "";

  jQuery.ajax({
    url: strUrl,
    success: function(html) {
      strReturn = html;
    },
    async:false
  });

  return strReturn;
}
于 2010-04-07T13:30:16.010 に答える
89

これらの回答はすべて、async:false を使用して Ajax 呼び出しを行うと、Ajax 要求が完了するまでブラウザーがハングするという点を見逃しています。フロー制御ライブラリを使用すると、ブラウザをハングアップせずにこの問題を解決できます。以下はFrame.jsの例です:

beforecreate: function(node,targetNode,type,to) {

    Frame(function(next)){

        jQuery.get('http://example.com/catalog/create/', next);
    });

    Frame(function(next, response)){

        alert(response);
        next();
    });

    Frame.init();
}
于 2012-04-28T17:41:39.133 に答える
53
function getURL(url){
    return $.ajax({
        type: "GET",
        url: url,
        cache: false,
        async: false
    }).responseText;
}


//example use
var msg=getURL("message.php");
alert(msg);
于 2012-04-25T15:34:38.047 に答える
30

注:async: false次の警告メッセージが表示されるため、使用しないでください。

Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27) 以降、メイン スレッドでの同期リクエストは、ユーザー エクスペリエンスへの悪影響のために非推奨になりました。

Chrome は、コンソールでこれについて警告します。

メイン スレッドでの同期 XMLHttpRequest は、エンド ユーザーのエクスペリエンスに悪影響を与えるため、推奨されていません。詳細については、https://xhr.spec.whatwg.org/を確認してください。

このようなことをしている場合、いつでも機能しなくなる可能性があるため、ページが壊れる可能性があります。

同期のように感じながらもブロックしないようにしたい場合は、async/await と、おそらく新しいFetch APIのようなプロミスに基づく ajax を使用する必要があります。

async function foo() {
  var res = await fetch(url)
  console.log(res.ok)
  var json = await res.json()
  console.log(json)
}

編集クロムは、ページがユーザーによって移動されているか閉じられているときに、ページの却下で同期 XHR を許可しない ことに取り組んでいます。これには、beforeunload、unload、pagehide、および visibilitychange が含まれます。

これがあなたのユースケースである場合は、代わりにnavigator.sendBeaconを見たいと思うかもしれません

ページが http ヘッダーまたは iframe の allow 属性を使用して同期要求を無効にすることも可能です。

于 2016-12-13T12:55:38.410 に答える
29

クロスドメイン Ajax 呼び出しを ( JSONPを使用して)実行している場合、同期的に実行できないasyncことに注意してください。フラグは jQuery によって無視されます。

$.ajax({
    url: "testserver.php",
    dataType: 'jsonp', // jsonp
    async: false //IGNORED!!
});

JSONP 呼び出しの場合、次を使用できます。

  1. 独自のドメインへの Ajax 呼び出し - サーバー側でクロスドメイン呼び出しを行う
  2. 非同期で動作するようにコードを変更する
  3. Frame.js のような「関数シーケンサー」ライブラリを使用します (この回答)
  4. 実行をブロックする代わりに UI をブロックする (この回答) (私のお気に入りの方法)
于 2015-05-10T06:28:53.557 に答える
17

Carcione からの回答を使用し、JSON を使用するように変更しました。

 function getUrlJsonSync(url){

    var jqxhr = $.ajax({
        type: "GET",
        url: url,
        dataType: 'json',
        cache: false,
        async: false
    });

    // 'async' has to be 'false' for this to work
    var response = {valid: jqxhr.statusText,  data: jqxhr.responseJSON};

    return response;
}    

function testGetUrlJsonSync()
{
    var reply = getUrlJsonSync("myurl");

    if (reply.valid == 'OK')
    {
        console.dir(reply.data);
    }
    else
    {
        alert('not valid');
    }    
}

「JSON」のdataTypeを追加し、 .responseTextresponseJSONに変更しました。

また、返されたオブジェクトのstatusTextプロパティを使用してステータスを取得しました。これは Ajax レスポンスのステータスであり、JSON が有効かどうかではないことに注意してください。

バックエンドは、正しい (整形式の) JSON で応答を返す必要があります。そうしないと、返されるオブジェクトが未定義になります。

元の質問に答える際に考慮すべき 2 つの側面があります。1 つは Ajax に ( async: falseを設定して) 同期的に実行するように指示する方法で、もう 1 つはコールバック関数ではなく、呼び出し元の関数の return ステートメントを介して応答を返す方法です。

POSTでも試してみましたが、うまくいきました。

GET を POST に変更し、データを追加しました: postdata

function postUrlJsonSync(url, postdata){

    var jqxhr = $.ajax({
        type: "POST",
        url: url,
        data: postdata,
        dataType: 'json',
        cache: false,
        async: false
    });

    // 'async' has to be 'false' for this to work
    var response = {valid: jqxhr.statusText,  data: jqxhr.responseJSON};

    return response;
}

上記のコードは、asyncfalseの場合にのみ機能することに注意してください。async: trueを設定した場合、返されたオブジェクトjqxhrは、AJAX 呼び出しが返された時点では有効ではなく、後で非同期呼び出しが終了したときに有効になりますが、応答変数を設定するには遅すぎます。

于 2014-11-15T11:33:46.987 に答える
9

これは例です:

$.ajax({
  url: "test.html",
  async: false
}).done(function(data) {
   // Todo something..
}).fail(function(xhr)  {
   // Todo something..
});
于 2014-08-16T13:20:10.440 に答える
6

まず、いつ $.ajax を使用し、いつ $.get/$.post を使用するかを理解する必要があります。

リクエスト ヘッダー設定、キャッシュ設定、同期設定など、ajax リクエストに対する低レベルの制御が必要な場合は、$.ajax を使用する必要があります。

$.get/$.post: ajax リクエストに対して低レベルの制御を必要としない場合。サーバーへのデータの単純な取得/投稿のみ。の略です

$.ajax({
  url: url,
  data: data,
  success: success,
  dataType: dataType
});

したがって、$.get/$.post で他の機能 (同期、キャッシュなど) を使用することはできません。

したがって、ajax リクエストに対する低レベルの制御 (同期、キャッシュなど) には、$.ajax を使用する必要があります。

 $.ajax({
     type: 'GET',
      url: url,
      data: data,
      success: success,
      dataType: dataType,
      async:false
    });
于 2017-10-03T09:52:59.623 に答える