javascript - jquery tooltip html




Wie kann ich jQuery dazu bringen, eine synchrone anstelle einer asynchronen Ajax-Anfrage auszuführen? (9)

Aus der jQuery-Dokumentation : Sie geben die asynchrone Option als false an, um eine synchrone Ajax-Anforderung zu erhalten. Dann kann Ihr Callback einige Daten setzen, bevor Ihre Mutterfunktion fortschreitet.

So würde Ihr Code aussehen, wenn er wie vorgeschlagen geändert wird:

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
    });
}

Ich habe ein JavaScript-Widget, das Standard-Erweiterungspunkte bietet. Einer von ihnen ist die beforecreate Funktion. Es sollte false , um zu verhindern, dass ein Objekt erstellt wird.

Ich habe mit jQuery einen Ajax-Aufruf in diese Funktion eingefügt:

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);
  });
}

Aber ich möchte verhindern, dass mein Widget das Element erstellt, daher sollte ich in der mother-Funktion false , nicht im Callback. Gibt es eine Möglichkeit, eine synchronisierte Ajax-Anfrage mit jQuery oder einer anderen API durchzuführen?


Ausgezeichnete Lösung! Ich bemerkte, als ich versuchte, es zu implementieren, dass, wenn ich einen Wert in der Erfolgsklausel zurückgab, es als undefined zurückkam. Ich musste es in einer Variablen speichern und diese Variable zurückgeben. Dies ist die Methode, die ich entwickelt habe:

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;
}

Da der synchrone XMLHttpReponse Vorgang veraltet ist, habe ich die folgende Lösung entwickelt, die XMLHttpRequest . Dies ermöglicht geordnete AJAX-Abfragen, die immer noch von Natur aus asynchron sind, was für CSRF-Token für den einmaligen Gebrauch sehr nützlich ist.

Es ist auch transparent, so dass Bibliotheken wie jQuery nahtlos funktionieren.

/* wrap XMLHttpRequest for synchronous operation */
var XHRQueue = [];
var _XMLHttpRequest = XMLHttpRequest;
XMLHttpRequest = function()
{
  var xhr   = new _XMLHttpRequest();
  var _send = xhr.send;

  xhr.send = function()
  {
    /* queue the request, and if it's the first, process it */
    XHRQueue.push([this, arguments]);
    if (XHRQueue.length == 1)
      this.processQueue();
  };

  xhr.processQueue = function()
  {
    var call = XHRQueue[0];
    var xhr  = call[0];
    var args = call[1];

    /* you could also set a CSRF token header here */

    /* send the request */
    _send.apply(xhr, args);
  };

  xhr.addEventListener('load', function(e)
  {
    /* you could also retrieve a CSRF token header here */

    /* remove the completed request and if there is more, trigger the next */
    XHRQueue.shift();
    if (XHRQueue.length)
      this.processQueue();
  });

  return xhr;
};

Dies ist ein Beispiel:

$.ajax({
  url: "test.html",
  async: false
}).done(function(data) {
   // Todo something..
}).fail(function(xhr)  {
   // Todo something..
});

Hinweis: Sie sollten Async deshalb nicht verwenden:

Seit Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27) sind synchrone Anfragen im Hauptthread aufgrund der negativen Auswirkungen auf die Benutzererfahrung veraltet.

Chrome warnt sogar davor in der Konsole:

Synchrone XMLHttpRequest auf dem Hauptthread wird aufgrund seiner nachteiligen Auswirkungen auf die Erfahrung des Endbenutzers nicht mehr empfohlen. Weitere Hilfe erhalten Sie unter https://xhr.spec.whatwg.org/ .

Dies könnte Ihre Seite beschädigen, wenn Sie so etwas tun, da es jeden Tag aufhören könnte zu arbeiten.

Wenn du es so machen willst, dass es sich immer noch anfühlt, als ob es synchron ist, aber trotzdem nicht blockiere, dann solltest du async / awaid verwenden und wahrscheinlich auch ein Ajax, das auf Versprechen wie der neuen Fetch API basiert

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

Ich habe die Antwort von Carcione benutzt und sie für JSON modifiziert.

 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');
    }    
}

Ich habe den Datentyp von 'JSON' hinzugefügt und den .responseText zu responseJSON geändert.

Ich habe den Status auch mithilfe der statusText- Eigenschaft des zurückgegebenen Objekts abgerufen. Beachten Sie, dass dies der Status der Ajax-Antwort ist, nicht ob der JSON gültig ist.

Das Back-End muss die Antwort in korrektem (wohlgeformtem) JSON zurückgeben, andernfalls ist das zurückgegebene Objekt nicht definiert.

Bei der Beantwortung der ursprünglichen Frage müssen zwei Aspekte berücksichtigt werden. Einer sagt Ajax, synchron zu arbeiten (indem async: false gesetzt wird ), und der andere gibt die Antwort über die return-Anweisung der aufrufenden Funktion und nicht in eine Callback-Funktion zurück.

Ich habe es auch mit POST versucht und es hat funktioniert.

Ich änderte den GET zu POST und fügte Daten hinzu : 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;
}

Beachten Sie, dass der obige Code nur funktioniert, wenn async falsch ist . Wenn Sie async: true setzen würden, wäre das zurückgegebene Objekt jqxhr zum Zeitpunkt der Rückgabe des AJAX-Aufrufs nicht gültig, erst später, wenn der asynchrone Aufruf beendet ist, aber das ist viel zu spät, um die Antwortvariable zu setzen.


Sie können das jjQuery-Ajax-Setup im synchronen Modus durch Aufruf von aufrufen

jQuery.ajaxSetup({async:false});

jQuery.get( ... ); dann Ihre Ajax-Aufrufe mit jQuery.get( ... );

Dann einfach einmal wieder einschalten

jQuery.ajaxSetup({async:true});

Ich denke, es funktioniert genauso wie von @Adam vorgeschlagen, aber es könnte hilfreich für jemanden sein, der seine jQuery.get() oder jQuery.post() zu der komplizierteren jQuery.ajax() Syntax umkonfigurieren jQuery.get() .


Wenn Sie einen domainübergreifenden Ajax-Aufruf durchführen (indem Sie JSONP ) - Sie können dies nicht synchron tun, das async Flag wird von jQuery ignoriert.

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

Für JSONP-Aufrufe könnten Sie verwenden:

  1. Ajax-Anruf zu Ihrer eigenen Domain - und tun Sie die Cross-Domain-Call-Server-Seite
  2. Ändern Sie Ihren Code, um asynchron zu arbeiten
  3. Verwenden Sie eine "Funktionssequenzer" -Bibliothek wie Frame.js (diese answer )
  4. Blockiere die Benutzeroberfläche, anstatt die Ausführung zu blockieren (diese answer ) (meine Lieblingsmethode)

function getURL(url){
    return $.ajax({
        type: "GET",
        url: url,
        cache: false,
        async: false
    }).responseText;
}


//example use
var msg=getURL("message.php");
alert(msg);




asynchronous