Bir sözün değerine nasıl erişilir?


146

Bu örneğe Angular'ın belgelerinden $qbakıyorum ama bunun muhtemelen genel olarak vaatler için geçerli olduğunu düşünüyorum. Aşağıdaki örnek, yorumları da dahil olmak üzere dokümanlarından kelimesi kelimesine kopyalanmıştır:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1

Bunun nasıl işlediğinden emin değilim. İlkinin .then()sonucunu arayabilirsem , .then()onları zincirleyebileceğimi biliyorum, o zaman promiseBtür bir söz nesnesi Object. Bu bir değil Number. Peki, "değeri 1 ile artırılan sözün sonucu olacak" ile ne demek istiyorlar?

Buna promiseB.valueböyle bir şey gibi mi erişmem gerekiyor ? Başarılı geri arama nasıl bir söz verebilir ve "sonuç + 1" i döndürebilir? Bir şey eksik.




Bu soru 5 yaşında ve kabul edilmiş bir cevabı var ...
temporary_user_name

@temporary_user_name: Eski sorularda bile insanların istedikleri zaman yakın oy kullanmaları sorun değil.
halfer

Yanıtlar:


141

promiseAbireyin thenfonksiyonu yeni bir söz (döndürür promiseBhemen sonra çözülürse) promiseAdeğeri içindeki başarı işlevinden döndürülen ne değerdir çözülene promiseA.

Bu durumda promiseAbir değerle çözülene - resultve sonra hemen giderir promiseBdeğeriyle result + 1.

Değerine promiseBerişim, sonuca eriştiğimiz şekilde yapılır promiseA.

promiseB.then(function(result) {
    // here you can use the result of promiseB
});

Aralık 2019'u Düzenle : async/ awaitartık JS'de standarttır, bu da yukarıda açıklanan yaklaşıma alternatif bir sözdizimi sağlar. Şimdi yazabilirsiniz:

let result = await functionThatReturnsPromiseA();
result = result + 1;

Şimdi hiçbir söz yok, çünkü sonucu promiseA'dan açtık awaitve doğrudan onunla çalışabilirsiniz.

Ancak, awaityalnızca bir asyncişlev içinde kullanılabilir . Bu nedenle, biraz uzaklaştırmak için, yukarıdaki gibi olmalıdır:

async function doSomething() {
    let result = await functionThatReturnsPromiseA();
    return result + 1;
}

2
Vaatler teorik olarak kendi nesneleridir. sözün başarı işlevi ile erişilebilen bir sonuç içerirler.
Nachshon Schwartz

2
Dolayısıyla, bir sözün eşzamansız geri aramasının dönüş değeri ile çalışmak istiyorsanız, başka bir eşzamansız geri aramanın içinde yapılması gerekir. Mantıklı. Nihai ilkel bir dönüş değeri elde etmenin bir yolunu arıyordum ama sanırım bu bağlam göz önüne alındığında nedene meydan okuyacaktır.
temporary_user_name

2
@Aerovistae aslında, ES6 bunu mümkün kılan jeneratörleri tanıtır ve ES7, her ikisi de size senkron kod gibi görünmesini sağlayan sözdizimleri üzerinde sözdizimi şekeri verir (arka planda bir durum makinesi çalıştırarak) - bu yüzden sıkı durun :)
Benjamin Gruenbaum

25

Bir söz çözüldüğünde / reddedildiğinde, başarı / hata işleyicisini çağırır:

var promiseB = promiseA.then(function(result) {
   // do something with result
});

thenPromiseB, / reddedilen çözülecektir: yöntem, aynı zamanda bir söz verir promiseâ gelen başarı / hata işleyicisi dönüş değerine bağlı .

PromiseB'nin sonucunu etkileyecek bir promiseA'nın başarı / hata işleyicilerinin geri verebileceği üç olası değer vardır:

1. Return nothing --> PromiseB is resolved immediately, 
   and undefined is passed to the success handler of promiseB
2. Return a value --> PromiseB is resolved immediately,
   and the value is passed to the success handler of promiseB
3. Return a promise --> When resolved, promiseB will be resolved. 
   When rejected, promiseB will be rejected. The value passed to
   the promiseB's then handler will be the result of the promise

Bu anlayışla donanmış olarak aşağıdakileri anlayabilirsiniz:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

Sonra çağrı hemen promiseB döndürür. PromiseA çözüldüğünde sonucu promiseA'nın başarı işleyicisine iletir. Dönüş değeri promiseA'nın sonucu + 1 olduğundan, başarı işleyicisi bir değer döndürüyor (yukarıdaki seçenek 2), bu nedenle promiseB hemen çözülecek ve promiseB'nin başarı işleyicisi promiseA'nın sonucu + 1'den geçecektir.


4

.thenpromiseB işlevi, promiseA işlevinden döndürülen şeyi alır .then.

Burada promiseA döndürüyor promiseB'nin numberbaşarı fonksiyonunda parametre olarak kullanılabilecek bir sayıdır. daha sonra 1 artırılacak


3

Yorumu mevcut anlayışınızdan biraz farklı ayrıştırmak yardımcı olabilir:

// promiseB will be resolved immediately after promiseA is resolved

Bu promiseBbir söz olduğunu ancak çözüldükten hemen sonra çözüleceğini belirtir promiseA. Buna bakmanın bir başka yolu promiseA.then()da, atanmış olan bir vaadi geri döndürmek demektir promiseB.

// and its value will be the result of promiseA incremented by 1

Bu , çözülen değerin successCallback değeri olarak alacak promiseAdeğer olduğu anlamına gelir promiseB:

promiseB.then(function (val) {
  // val is now promiseA's result + 1
});

2

pixelbits yanıtı doğrudur ve her zaman .then()üretim kodundaki bir vaat değerine erişmek için kullanmalısınız .

Ancak, söz konusu değerin, aşağıdaki desteklenmeyen dahili node.js bağlaması kullanılarak çözüldükten hemen sonra erişmenin bir yolu vardır:

process.binding('util').getPromiseDetails(myPromise)[1]

UYARI: süreç bağlama hiçbir zaman nodejs çekirdeğinin dışında kullanılmak üzere tasarlanmamıştı ve nodejs çekirdek ekibi aktif olarak kullanımdan kaldırmak istiyor

https://github.com/nodejs/node/pull/22004 https://github.com/nodejs/node/issues/22064


1

Bu örnek kendini açıklayıcı buluyorum. Sonucu nasıl beklediğine dikkat edin ve bu yüzden iade edilen Sözü kaçırdınız.

cryA = crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
Promise {<pending>}
cryB = await crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
{publicKey: CryptoKey, privateKey: CryptoKey}

Bu, zaman uyumsuz bir işlev içinde olmalıdır.
Samed

0
promiseA(pram).then(
     result => { 
     //make sure promiseA function allready success and response
     //do something here
}).catch(err => console.log(err)) => {
     // handle error with try catch
}

1
Bu kod soruyu cevaplayabilirken, sorunun nasıl ve neden çözüldüğüne dair ek bağlam sağlamak yanıtlayıcının uzun vadeli değerini artıracaktır.
Alexander

0

Javascript'te zaman uyumsuz bir bekleme yöntemi kullanarak bunu kolayca yapabilirsiniz.

Aşağıda, zaman aşımı kullanarak bir WebRTC vaat değeri alma örneği verilmiştir.

function await_getipv4(timeout = 1000) {
    var t1 = new Date();
    while(!window.ipv4) {
        var stop = new Date() - t1 >= timeout;
        if(stop) {
            console.error('timeout exceeded for await_getipv4.');
            return false;
        }
    }
    return window.ipv4;
}

function async_getipv4() {
    var ipv4 = null;
    var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}})
    findIP.then(ip => window.ipv4 = ip);
    return await_getipv4();
};


Bu snippet'i burada çalıştırmak önemli değil, ancak gerçek bir tarayıcıda, bunun sanal alandan kaynaklandığına inanıyorum.
OxFEEDFACE

0

Düğüm REPL, bir vaat değeri olan bir DB bağlantısı almak için, aşağıdaki yaklaşımı aldı:

let connection
try {
  (async () => {
    connection = await returnsAPromiseResolvingToConnection()
  })()
} catch(err) {
  console.log(err)
}

Çizgisi awaitnormalde bir söz verir. Bu kod Düğüm REPL'sine yapıştırılabilir veya kaydedilmişse index.jsBash ile çalıştırılabilir.

node -i -e "$(< index.js)"

Bu, komut dosyasını set değişkenine erişerek çalıştırdıktan sonra Düğüm REPL'inde bırakır. Eşzamansız işlevin geri döndüğünü doğrulamak connectioniçin, örneğin günlüğe kaydedebilirsiniz ve sonra değişkeni kullanmaya hazırsınız. Tabii ki, eşzamansız fonksiyonun dışındaki koddaki herhangi bir kod için henüz çözülmemiş olan eşzamansız işlevine güvenmek istemez.


0

Yukarıda bazı iyi cevaplar var ve işte ES6 Ok işlevi sürümü

var something = async() => {
   let result = await functionThatReturnsPromiseA();
   return result + 1;
}

0

Javascript vaatlerinin yavaş öğreneniyim, varsayılan olarak tüm eşzamansız işlevler bir söz veriyor, sonucunuzu şu şekilde sarabilirsiniz:

(async () => {
//Optional "await"
  await yourAsyncFunctionOrPromise()
    .then(function (result) {
      return result +1;
    })
    .catch(function (error) {
      return error;
    })()
})

" Bekleme ifadesi, bir Vaat yerine getirilene kadar (yani, yerine getirilen veya reddedilen) zaman uyumsuz işlev yürütmesinin duraklamasına ve yerine getirildikten sonra zaman uyumsuz işlevinin yürütülmesine devam edilmesine neden olur. Devam edildiğinde, beklenen ifadenin değeri yerine getirilen Sözün değeridir. Eğer Söz reddedilirse, beklenen ifade reddedilen değeri atar . "

Hakkında daha fazla bilgi okuyun bekliyoruz ve vaatler de MDN Web Dokümanlar


-5

Belki bu küçük dizgi kodu örneği yardımcı olacaktır.

private getAccount(id: Id) : Account {
    let account = Account.empty();
    this.repository.get(id)
        .then(res => account = res)
        .catch(e => Notices.results(e));
    return account;
}

İşte repository.get(id)döndürür a Promise<Account>. Bunu deyim accountiçindeki değişkene thenatarım.


1
Promisse çözülmeden önce kodunuz hesabı döndürüyor ve bu yüzden aşağı oy verildi, kodunuz daima Account.empty ();
Felype
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.