Dönen değer veya Promise.resolve arasındaki fark nedir ()


314

Arasındaki fark nedir:

new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return "bbb";
  })
  .then(function(result) {
    console.log(result);
  });

ve bu:

new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return Promise.resolve("bbb");
  })
  .then(function(result) {
    console.log(result);
  });

Farklı davranışlar alıyorum gibi soruyorum Zincirleme .then () ile Angular ve $ http hizmetini kullanma. Biraz fazla kod dolayısıyla ilk örnek yukarıdaki.


1
Hangi "farklı davranışları" görüyorsunuz? Her iki örnek de aynı şekilde çalışmalı ve davranmalıdır. Promise.resolve()İkinci örnekte gereksizdir.
JLRishe

4
@pixelbits Bir thenişleyiciden bir söz vermenin yanlış bir yanı yoktur , aslında, bunu yapabileceğiniz sözlerin özelliğinin önemli bir yönüdür.

Bunun keyfi olarak iç içe yerleştirilmiş thens ile çalıştığını unutmayın - bunun için 'diğer diller' terimi thenhem a hem de mapa flatMap.
Benjamin Gruenbaum

1
2. satırda neden res ("aaa") öğesini çağırmak zorundasınız, neden "aaa" yı geri döndüremiyorsunuz ve Promise bunu çözümlemek için yakalar (), reddetme () için de istisnaları yakalar gibi?
Sam Liddicott

1
@SamLiddicott aynı soruya sahipken, mayınlar biraz daha karmaşık: new Promise((res, rej) => { return fetch('//google.com').then(() => { return "haha"; }) }).then((result) => alert(result));Bu kod sadece asılacak (sonsuza kadar çözülmeyecek). Ama eğer değiştirirsem işe yarayacak ve "haha" return "haha";return res("haha");uyaracaktır. Fetch (). Then () zaten "haha" yı çözülmüş bir vaatte sarmadı mı?
Shaung Cheng

Yanıtlar:


138

İse fonksiyon ise kural olduğunu thenişleyicisi bu değerle bir değer, söz giderir / ıskarta döndürür ve fonksiyon bir söz dönerse, olduğunu ne olur, bir sonraki thenhüküm olacak thenbir fıkra iade işlevi söz böylece, bu durumda, ilk örnek normal dizisi boyunca düşer thensbunu yaptığında bir, ikinci örnekte, söz nesne döndürülmeden olduğunu Tahmin edebileceğiniz gibi değerler üzerinden ve baskılar Promise.resolve("bbb")ardından 's olduğu thenzaman zincirleme çağrılan, o (tüm niyetler ve amaçlar için). Aslında çalışma şekli aşağıda daha ayrıntılı olarak açıklanmaktadır.

Promises / A + spesifikasyonlarından alıntı:

Vaat çözüm prosedürü, girdi olarak bir vaat ve bir değer olarak tanımladığımız soyut bir işlemdir [[Resolve]](promise, x). Eğer xbir yenilebilir ise, x'in en azından bir vaat gibi davrandığı varsayılarak, vaat edilme durumunux vaat etmeye çalışır . Aksi takdirde, değer vaadini yerine getirir x.

Alacaklıların bu tedavisi, bir Promises / A + uyumlu ve sonra yöntemi ortaya koydukları sürece söz verilen uygulamaların birlikte çalışmasına izin verir. Ayrıca Promises / A + uygulamalarının uygun olmayan uygulamaları makul ve daha sonra yöntemlerle “özümsemesine” izin verir.

Burada dikkat edilmesi gereken en önemli şey şu:

eğer xbir sözdür, onun durumunu benimsemek [3.4]

bağlantı: https://promisesaplus.com/#point-49


4
"Durumunu benimseyin", bir thenişleyici bir söz verdiğinde davranışı ifade etmenin kısa ve kullanışlı bir yoludur . Spesifikasyon referansı için +1.

69
Aslında - buradaki spesifikasyonun ilgili kısmı, [[Resolve]]hem thenables hem de değerlerde çağrılan gerçeğidir, bu yüzden aslında bir değeri vaatle sarar, bu yüzden return "aaa"aynıdır return Promise.resolve("aaa")ve return Promise.resolve("aaa")aynıdır return Promise.resolve(Promise.resolve("aaa"))- çünkü kararlılık onu daha fazla bir değere çağırmak idempotenttir bir kereden fazla aynı sonucu verir.
Benjamin Gruenbaum

8
@Benjamin Gruenbaum , her durumda geri dönüşün "aaa"ve ables'te return Promise.resolve("aaa")değiştirilebilir olduğu anlamına thenmı geliyor?
CSnerd

9
Evet, tam olarak anlamı bu.
Benjamin Gruenbaum

118

Basit bir ifadeyle, bir thenişleyici işlevinin içinde:

A) Ne zaman xbir değer (sayı, dize vb.):

  1. return x eşittir return Promise.resolve(x)
  2. throw x eşittir return Promise.reject(x)

B) xHalihazırda kararlaştırılmış bir Vaat (artık beklemede değil):

  1. return xreturn Promise.resolve(x)Promise zaten çözülmüşse , eşdeğeridir .
  2. return xreturn Promise.reject(x)Sözün zaten reddedilmesi durumunda eşdeğerdir .

C) xBekleyen bir Söz ne zaman :

  1. return xBekleyen bir Sözü geri gönderir ve daha sonra değerlendirilir then.

Bu konu hakkında Promise.prototype.then () belgelerinde daha fazla bilgi edinin .


93

Her iki örneğiniz de hemen hemen aynı şekilde davranmalıdır.

Bir then()işleyicinin içinde döndürülen bir değer, bundan döndürülen vaatin çözüm değeri olur then(). İçinde döndürülen değer .then bir söz ise, geri verilen söz bu sözün then()"durumunu kabul eder" ve geri verilen sözün yaptığı gibi çözer / reddeder.

İlk örneğinizde, "bbb"ilk then()işleyiciye dönersiniz , böylece bir "bbb"sonraki then()işleyiciye aktarılır .

İkinci örnekte, derhal değerle çözülene bir söz dönmek "bbb"yüzden, "bbb"bir sonraki geçirilir then()işleyicisi. (Burası Promise.resolve()aşırı).

Sonuç aynı.

Bize gerçekten farklı davranışlar sergileyen bir örnek gösterebilirseniz, bunun neden olduğunu size söyleyebiliriz.


1
Güzel cevap! Promise.resolve();Vs ne olacak return;?
FabianTe

2
@FabianTe Bunlar, undefinedbunun yerine , aynı etkiye sahip olurlar "bbb".
JLRishe

51

Zaten iyi bir resmi cevabın var. Kısa bir tane eklemem gerektiğini düşündüm.

Aşağıdaki şeyler Promises / A + vaatleriyle aynıdır :

  • Arama Promise.resolve(Açısal davanızda $q.when)
  • Söz yapıcısını çağırmak ve çözümleyicisinde çözümlemek. Senin durumunda new $q.
  • Geri aramadan değer döndürme then.
  • Değeri olan bir dizide Promise.all öğesini çağırıp bu değeri ayıklayın.

Dolayısıyla, aşağıdakilerin tümü bir söz veya düz X değeri için aynıdır:

Promise.resolve(x);
new Promise(function(resolve, reject){ resolve(x); });
Promise.resolve().then(function(){ return x; });
Promise.all([x]).then(function(arr){ return arr[0]; });

Ve bu hiç de şaşırtıcı değil, vaatlerin belirtilmesi, kütüphaneler arasında ($ q ve yerel vaatler gibi) kolay birlikte çalışmayı sağlayan ve hayatınızı daha kolay hale getiren Vaat Çözüm Prosedürü'ne dayanıyor . Ne zaman bir vaat kararı ortaya çıkarsa, genel tutarlılık yaratan bir çözüm oluşur.


ne yapmak istediğini sorabilir miyim Promise.resolve().then(function(){ return x; });? Benzer bir şey ( thenblok içinde bir işlev denir) yaparak bir snip buldum . Az ya da çok zaman aşımı yapmayı düşündüm, ama biraz daha hızlı. jsben.ch/HIfDo
Sampgun

Olguların% 99,99'unda Promise.resolve (x) ile aynı şey yoktur. (% 0.001, istisna atan bir özellik erişimcisi olan withbir nesne veya proxy üzerinde bir blokta olduğumuzdur x. Bu durumda Promise.resolve (x) atılan bir hataya neden olur, ancak Promise.resolve().then(function(){ return x; });hata atıldığından beri reddedilen bir vaat olur a then).
Benjamin Gruenbaum

boş bir yıldırım bağladınız ya da tasarruf etmediniz. Her neyse, ifadeler arasındaki farklar hakkında konuşmuyordum. Tam olarak yazdıklarım hakkında konuşuyordum. Sadece daha açık olmak gerekirse, bu bahsettiğim snippet'tir: if (validator) { Promise.resolve().then(() => { this._cdRef.markForCheck(); }); }. Burada söz verilmiyor, ne anlamı var? Zaman aşımı (aşağı yukarı) aynı etkiye sahip olur mu, olmaz mı?
Sampgun

1
Tüm senkron kodlar meydana geldikten sonra ancak herhangi bir G / Ç gerçekleşmeden önce çağrıyı eşzamansız olarak gerçekleştirir. Buna "mikrotick semantiği" denir.
Benjamin Gruenbaum

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.