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);
});
Ş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.
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's
polyfill()`](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:
jQuery'nin gelecekteki sürümleri (3.x'ten başlayarak - Mayıs 2015 itibariyle mevcut kararlı sürümler 1.x ve 2.x'tir) Promises/A+ spesifikasyonu ile uyumlu olacaktır (yorumlarda işaret ettiği için Benjamin Gruenbaum'a teşekkürler). "Halihazırda karar verdiğimiz iki değişiklik, Ertelenmiş uygulamamız için Promise/A+ uyumluluğudur [...]" (jQuery 3.0 ve Web geliştirmenin geleceği). Daha fazla bilgi için bkz: Dave Methvin tarafından yazılan jQuery 3.0: The Next Generations ve Paul Krill tarafından yazılan jQuery 3.0: More interoperability, less Internet Explorer.
ECMA-262, 6. Baskı, Bölüm 14.2](http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions)'de arrow functions adı verilen ve yukarıdaki örnekleri daha da basitleştirmek için kullanılabilecek yeni bir sözdizimi vardır. jQuery API'sini kullanarak, yerine:
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(alert)
kullanabilirdiniz, çünkü sadece alert
öğesini geri aramanızla aynı argümanlarla çağırıyorsunuz, ancak ok sözdizimi daha geneldir ve aşağıdaki gibi şeyler yazmanıza olanak tanır: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:
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:
ve
await` için yerel desteğinizin olmadığı yerlerde Babel'i kullanabilirsiniz:co
veya Bluebird korutinlerinde olduğu gibi jeneratör tabanlı bir yaklaşım:Daha fazla ayrıntı için vaatlerle ilgili diğer bazı sorular:
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.
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.