jQuery: Ajax çağrısı başarılı olduktan sonra veri döndürme

Bunun gibi bir şeyim var, bana bir değer, bir dize geri veren bir komut dosyasına basit bir çağrı...

function testAjax() {
    $.ajax({
      url: "getvalue.php",  
      success: function(data) {
         return data; 
      }
   });
}

ama eğer şöyle bir şey çağırırsam

var output = testAjax(svar);  // output will be undefined...

Peki değeri nasıl döndürebilirim? aşağıdaki kod da çalışmıyor gibi görünüyor...

function testAjax() {
    $.ajax({
      url: "getvalue.php",  
      success: function(data) {

      }
   });
   return data; 
}

Not: Bu cevap Şubat 2010'da yazılmıştır.
2015, 2016 ve 2017 güncellemelerini en altta görebilirsiniz.
Eşzamansız bir işlevden hiçbir şey döndüremezsiniz. Döndürebileceğiniz şey bir sözdür. Bu sorulara verdiğim cevaplarda jQuery'de vaatlerin nasıl çalıştığını açıkladım:

function testAjax() {
  $.ajax({
    url: "getvalue.php",  
    success: function(data) {
      return data; 
    }
  });
}

testAjax fonksiyonunuzu şu şekilde yazabilirsiniz:

function testAjax() {
  return $.ajax({
      url: "getvalue.php"
  });
}

O zaman sözünüzü bu şekilde alabilirsiniz:

var promise = testAjax();

Sözünüzü saklayabilir, etrafta dolaştırabilir, fonksiyon çağrılarında argüman olarak kullanabilir ve fonksiyonlardan döndürebilirsiniz, ancak sonunda AJAX çağrısı tarafından döndürülen verilerinizi kullanmak istediğinizde, bunu şu şekilde yapmanız gerekir:

promise.success(function (data) {
  alert(data);
});

(Basitleştirilmiş sözdizimi için aşağıdaki güncellemelere bakın.) Verileriniz bu noktada mevcutsa, bu işlev hemen çağrılacaktır. Eğer mevcut değilse, veriler mevcut olur olmaz çağrılacaktır. Tüm bunları yapmanın amacı, asenkron olduğu için $.ajax çağrısından hemen sonra verilerinizin mevcut olmamasıdır. Promises, fonksiyonlar için güzel bir soyutlamadır: Verileri size geri veremem çünkü henüz elimde değil ve sizi engellemek ve bekletmek istemiyorum, bu yüzden işte bunun yerine bir vaat* ve daha sonra kullanabileceksiniz ya da sadece başka birine verip işinizi bitirebileceksiniz. Bunu görün [DEMO](http://jsfiddle.net/jW68r/). GÜNCELLEME (2015)

Şu anda (Mart 2015 itibariyle) jQuery Promises Promises/A+ spesifikasyonu ile uyumlu değildir, bu da diğer Promises/A+ uyumlu uygulamalar ile çok iyi işbirliği yapamayabilecekleri anlamına gelir. Ancak gelecek 3.x sürümündeki jQuery Promises **Vaatler/A+ spesifikasyonu ile uyumlu olacaktır (bunu belirttiği için Benjamin Gruenbaum'a teşekkürler). Şu anda (Mayıs 2015 itibariyle) jQuery'nin kararlı sürümleri 1.x ve 2.x'tir.

Yukarıda (Mart 2011'de) açıkladığım şey, jQuery Deferred Objects kullanarak senkron kodda bir değer döndürerek elde edilecek bir şeyi asenkron olarak yapmanın bir yoludur. Ancak bir senkron fonksiyon çağrısı iki şey yapabilir - ya bir değer döndürebilir (eğer döndürebilirse) ya da bir istisna fırlatabilir (eğer bir değer döndüremezse). Promises/A+, bu kullanım durumlarının her ikisini de senkron koddaki istisna işleme kadar güçlü bir şekilde ele alır. JQuery versiyonu bir değer döndürme eşdeğerini gayet iyi bir şekilde ele alır, ancak karmaşık istisna işleme eşdeğeri biraz sorunludur. Özellikle, senkron kodda istisna işlemenin tüm amacı sadece güzel bir mesajla pes etmek değil, sorunu çözmeye çalışmak ve yürütmeye devam etmek veya muhtemelen programın diğer bölümlerinin ele alması için aynı veya farklı bir istisnayı yeniden atmaktır. Senkron kodda bir çağrı yığınınız vardır. Asenkron çağrıda böyle bir şey yoktur ve Promises/A+ spesifikasyonunun gerektirdiği şekilde vaatlerinizin içinde gelişmiş istisna işleme, karmaşık kullanım durumları için bile hataları ve istisnaları anlamlı bir şekilde ele alacak kod yazmanıza gerçekten yardımcı olabilir. jQuery ve diğer uygulamalar arasındaki farklar ve jQuery vaatlerinin Vaatler/A+ uyumlu hale nasıl getirileceği için Q kütüphanesi wiki'sinde Kris Kowal ve diğerleri tarafından yazılan Coming from jQuery ve HTML5 Rocks'ta Jake Archibald tarafından yazılan Promises arrive in JavaScript adlı makalelere bakın.

Gerçek bir söz nasıl döndürülür

Yukarıdaki örneğimde yer alan fonksiyon:

function testAjax() {
  return $.ajax({
      url: "getvalue.php"
  });
}

bir jQuery Ertelenmiş Nesne olan bir jqXHR nesnesi döndürür. Gerçek bir promise döndürmek için, Q wiki'deki yöntemi kullanarak - olarak değiştirebilirsiniz:

function testAjax() {
  return Q($.ajax({
      url: "getvalue.php"
  }));
}

veya HTML5 Rocks makalesindeki yöntemi kullanarak:

function testAjax() {
  return Promise.resolve($.ajax({
      url: "getvalue.php"
  }));
}

Bu Promise.resolve($.ajax(...)) aynı zamanda promise modülü belgelerinde açıklanan ve ES6 Promise.resolve() ile çalışmalıdır. ES6 Promisesi bugün kullanmak için Jake Archibald tarafından [es6-promise module'spolyfill()`](https://github.com/jakearchibald/es6-promise#auto-polyfill) kullanabilirsiniz. ES6 Promises'i polyfill olmadan nerede kullanabileceğinizi görmek için bkz: Can I use: Promises. Daha fazla bilgi için bkz:

promise.success(function (data) {
  alert(data);
});

yazabilirsin:

promise.success(data => alert(data));

veya Promises/A+ API'sini kullanarak yapabilirsiniz:

promise.then(data => alert(data));

Reddetme işleyicilerini her zaman ile kullanmayı unutmayın:

promise.then(data => alert(data), error => alert(error));

ya da ile:

promise.then(data => alert(data)).catch(error => alert(error));

Neden her zaman vaatlerle birlikte ret işleyicileri kullanmanız gerektiğini görmek için bu yanıta bakın:

promise.then(data => alert("x is " + data.x));

Henüz her tarayıcı bu sözdizimini desteklemiyor, ancak kodunuzun hangi tarayıcıda çalışacağından emin olduğunuz bazı durumlar vardır - örneğin bir Chrome uzantısı, bir Firefox Eklentisi veya Electron, NW.js veya AppJS kullanan bir masaüstü uygulaması yazarken (ayrıntılar için bu yanıta bakın). Ok fonksiyonlarının desteği için bkz:

  • Şu anda bu kod yerine yeni bir await anahtar sözcüğüne sahip async fonksiyonları adı verilen daha da yeni bir sözdizimi var:
functionReturningPromise()
    .then(data => console.log('Data:', data))
    .catch(error => console.log('Error:', error));

yazmanızı sağlar:

try {
    let data = await functionReturningPromise();
    console.log('Data:', data);
} catch (error) {
    console.log('Error:', error);
}

Bunu yalnızca async anahtar sözcüğü ile oluşturulan bir işlevin içinde kullanabilirsiniz. Daha fazla bilgi için bkz:

Yorumlar (9)
Çözüm

Fonksiyondan veri döndürmenin tek yolu asenkron çağrı yerine senkron çağrı yapmaktır, ancak bu da tarayıcının yanıtı beklerken donmasına neden olur.

Sonucu işleyen bir geri arama işlevi iletebilirsiniz:

function testAjax(handleData) {
  $.ajax({
    url:"getvalue.php",  
    success:function(data) {
      handleData(data); 
    }
  });
}

Şöyle diyelim:

testAjax(function(output){
  // here you use the output
});
// Note: the call won't wait for the result,
// so it will continue with the code here while waiting.
Yorumlar (7)

Jquery dokümanları örneğine bakın: http://api.jquery.com/jQuery.ajax/ (sayfanın yaklaşık 2/3'ü)

Aşağıdaki kodu arıyor olabilirsiniz:

    $.ajax({
     url: 'ajax/test.html',
     success: function(data) {
     $('.result').html(data);
     alert('Load was performed.');
   }
});

Aynı sayfa... daha aşağıda.

Yorumlar (0)