Bir fonksiyonun değişkenini döndürmeden önce bir sözün bitmesini nasıl beklerim?


149

Hala vaatlerle mücadele ediyorum, ama buradaki topluluk sayesinde biraz ilerleme kaydediyorum.

Bir ayrıştırma veritabanı sorgulayan basit bir JS işlevi var. Sonuç dizisini döndürmesi gerekiyordu, ancak açıkça sorgunun eşzamansız doğası (dolayısıyla vaatler) nedeniyle, işlev sonuçlardan önce geri dönerek beni tanımsız bir dizi ile bırakıyor.

Bu fonksiyonun sözün sonucunu bekletmesi için ne yapmam gerekir?

İşte benim kod:

function resultsByName(name)
{   
    var Card = Parse.Object.extend("Card");
    var query = new Parse.Query(Card);
    query.equalTo("name", name.toString());

    var resultsArray = [];

    var promise = query.find({
               success: function(results) {
               // results is an array of Parse.Object.
                             console.log(results);
                             //resultsArray = results;
                             return results;
               },

               error: function(error) {
               // error is an instance of Parse.Error.
                             console.log("Error");
               }
    });                           

}

3
Ayrıca, zaman uyumsuz / beklemeyi kullanmayı da düşünebilirsiniz. Düğüm şimdi destekler zaman uyumsuz / bekliyoruz kutudan beri sürüm 7.6
Viliam Simko

Yanıtlar:


66

Bir döndürmek yerine resultsArraybir sonuç dizisi için bir söz döndürür ve daha sonra thençağrı sitesinde - bu fonksiyonun zaman uyumsuz G / Ç gerçekleştirdiğini bilerek arayanın ek yararı vardır. Eşzamanlılığı JavaScript'te kodlamak buna dayanır - daha geniş bir fikir edinmek için bu soruyu okumak isteyebilirsiniz :

function resultsByName(name)
{   
    var Card = Parse.Object.extend("Card");
    var query = new Parse.Query(Card);
    query.equalTo("name", name.toString());

    var resultsArray = [];

    return query.find({});                           

}

// later
resultsByName("Some Name").then(function(results){
    // access results here by chaining to the returned promise
});

Ayrıştırma sözlerini Parse'nin kendi blog gönderisinde sorgularla kullanma konusunda daha fazla örnek görebilirsiniz .


bana bunun desteğinin ne olduğunu söyleyebilir misin? IE9 bunu destekliyor mu?
sandrina-p

Evet, ama Parse'nin kendisi çoğunlukla öldü, bu yüzden @SandrinaPereira. Bu ayrıştırma bulut kodudur.
Benjamin Gruenbaum

1
Ah bu sadece saf javascript değil mi? Bunu yapmak için bir yol arıyordum (başka bir işlevi başlatmak için bitirmek için bir işlev bekleyin) ama sadece saf javascript ile ..
sandrina-p

Soru, sözleri değil, ayrıştırma koduyla ilgilidir. Vaatler (bir kütüphane ile) herhangi bir tarayıcıda çalışabilir. Bluebird IE6 ve netscape 7'de çalışıyor
Benjamin Gruenbaum

1
Ben iki gündür SO okuyorum ve yine de, kimse bunu çözmedi. Bu kabul edilen cevap birbiriyle aynıdır. İşlev, OP'nin istediği değeri değil bir Promise değerini döndürür. Bu cevap neden kabul edildi olarak işaretlendi?
19'da iGanja

19

Bu fonksiyonun sözün sonucunu bekletmesi için ne yapmam gerekir?

Kullanım async/await(ECMA6'nın bir parçası DEĞİL, ancak 2017 sonundan beri Chrome, Edge, Firefox ve Safari için kullanılabilir, bkz. CanIuse )
MDN

    async function waitForPromise() {
        // let result = await any Promise, like:
        let result = await Promise.resolve('this is a sample promise');
    }

Yorum nedeniyle eklendi: Zaman uyumsuz bir işlev her zaman bir Promise döndürür ve TypeScript'te şöyle görünür:

    async function waitForPromise(): Promise<string> {
        // let result = await any Promise, like:
        let result = await Promise.resolve('this is a sample promise');
    }

4
Async işlevi, beklemeden (veya eşzamansız olmayan kodda) çağrılırsa yine de bir sözlü nesne döndürür. Emin değilseniz console.log (waitForPromise ()) sonucunu kontrol edin. Zaman uyumsuz fonksiyonu içinde console.log (sonuç) maddesinin kontrolünde olacak beklediğiniz çıktısını ama zaman uyumsuz işlevinden dönüş söz engelleme ve iadeler olmadan hemen gerçekleşir. Javascript'te engelleme genellikle tek bir dişli uygulama olduğundan çok kötüdür ve engelleme, tüm uygulamayı dizlerine getiren diğer pub / alt istemcileri aç bırakacaktır.
SRM

1
.net görev sınıfı gibi "promise" de .wait () içerir. Javascript'te bu özellik eksik mi? Başka bir araca çıkış boru olabilir benim düğüm komut satırı aracından çıkmadan önce bir şey beklemek gerekiyor. "await" yalnızca zaman uyumsuz işlevlerin içinde çalışır. Yani bir sözün kapsamı dışında çalışmaz.
TamusJRoyce

@SRM Yorumunuzun numunenin yanlış yorumlanmasına dayandığını hissediyorum - bu "iç" Promise.resolve (en basit Promise örneği olarak) ile ilgili olduğundan, yorumunuzda belirttiğiniz gibi dış arayan yoktur. Bu yüzden cevabı güncellemeye karar verdim.
Martin Meeser

@TamusJRoyce Sanırım bu kendi başına bir soru ama C # 'de Task.ContinueWith (Görev) kullanabilirsiniz, hangi kabul edilen cevap ("sonra ()" denir) aynı fikir.
Martin Meeser

Sanırım şimdi görüyorum. Tüm betiğimi büyük bir zaman uyumsuz işlevinde sarabilirim. Ve bu fonksiyonu senaryomun son satırı olarak adlandır. Bu fonksiyon hala biraz kazan plakası olacaktır. Ama daha önce algıladığımdan çok daha az. İşlevler içindeki işlevleri yazmaya alışkın değilim. Teşekkürler @MartinMeeser!
TamusJRoyce

3

JavaScript'in engelleme olmaması amaçlandığından işlevi bekletmek istemezsiniz. Bunun yerine, fonksiyonun sonunda vaadi döndürürseniz, çağıran fonksiyon sunucu cevabını almak için vaadi kullanabilir.

var promise = query.find(); 
return promise; 

//Or return query.find(); 

1
success:Bit ile tüm geri aramalarınız kapalı.
Benjamin Gruenbaum

Ya da daha iyisi: return query.find();.
mash

Ayrıca tamam. Sadece açıklama amacıyla bu şekilde bırakacağım ama yorum olarak ekleyeceğim.
İz

Bunu denedim ama sonuçlar tanımsız görünüyor. resultsByName ("ad"). sonra (function (results) {console.log ("got array" + results.count);});
mac_55

1
Teşekkürler, sonuçlar işlevi içinde bir tür hata olmalı. Şuan çalışıyor.
Console.log'umu

2

Aslında burada vaatler kullanmıyorsunuz. Ayrıştırma, geri aramaları veya vaatleri kullanmanıza olanak tanır; senin seçimin.

Vaatleri kullanmak için aşağıdakileri yapın:

query.find().then(function() {
    console.log("success!");
}, function() {
    console.log("error");
});

Şimdi, söz tamamlandıktan sonra bir şeyler yürütmek için, söz konusu öğeyi çağrı içindeki sözlü geri arama içinde yürütebilirsiniz then(). Şimdiye kadar bu normal geri aramalarla tamamen aynı olurdu.

Sözleri gerçekten iyi kullanmak, onları zincirlediğiniz zamandır, şöyle:

query.find().then(function() {
    console.log("success!");

    return new Parse.Query(Obj).get("sOmE_oBjEcT");
}, function() {
    console.log("error");
}).then(function() {
    console.log("success on second callback!");
}, function() {
    console.log("error on second callback");
});

Sonuç nesnesi ne tür bir nesnedir?
dizimi

Bu bir dizi olmalıdır Parse.Object.
püre
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.