Promise.resolve - yeni Promise (çözümleme)


98

Bluebird kullanıyorum ve eşzamanlı işlevleri bir Söze dönüştürmenin iki yolunu görüyorum, ancak her iki yol arasındaki farkları anlamıyorum. Stacktrace biraz farklı gibi görünüyor, bu yüzden sadece bir değil alias, değil mi?

Peki tercih edilen yol nedir?

Yol A

function someFunction(someObject) {
  return new Promise(function(resolve) {
    someObject.resolved = true;
    resolve(someObject);
  });
}

Yol B

function someFunction(someObject) {
  someObject.resolved = true;
  return Promise.resolve(someObject);
}

3
Promise.resolvesadece şekerdir.
Qantas 94 Heavy

1
Kısa cevap - kullanımda farklılık yok. Sadece şeker.
Pinal

@Pinal "Şeker" nedir?
doubleOrt

6
@Boğa Burcu. Sözdizimsel şeker , şeyleri okumayı veya ifade etmeyi kolaylaştırmak için tasarlanmış sözdizimidir. bkz: wikipedia .
Wyck

Yanıtlar:


85

Yorumlardaki her iki cevabın aksine - bir fark var.

Süre

Promise.resolve(x);

temelde aynıdır

new Promise(function(r){ r(x); });

bir incelik var.

Promise döndüren işlevler, zaman uyumsuz olarak atabilecekleri için genellikle eşzamanlı olarak atmamaları gerektiğine dair garantiye sahip olmalıdır. Beklenmeyen sonuçları ve yarış koşullarını önlemek için - atışlar genellikle geri dönen retlere dönüştürülür.

Bunu akılda tutarak - şartname oluşturulduğunda, vaat eden kurucu güvende olur.

Ya someObjectolduğunu undefined?

  • A Yolu, reddedilmiş bir söz verir.
  • Way B eşzamanlı olarak atar.

Bluebird bunu gördü ve Petka, Promise.methoddönüş değerlerini kullanmaya devam edebilmeniz için bu sorunu çözmek için ekledi . Yani bunu Bluebird'de yazmanın doğru ve en kolay yolu aslında hiçbiri - bu:

var someFunction = Promise.method(function someFunction(someObject){
    someObject.resolved = true;
    return someObject;
});

Promise.method, atışları reddetmeye dönüştürür ve sizin için çözümlere döner. Bunu yapmanın en güvenli yoludur ve thengeri dönüş değerleri aracılığıyla yetenekleri özümser, böylece someObjectaslında bir söz olsa bile işe yarar .

Genel olarak, Promise.resolvevaatlere nesneler ve yabancı vaatler (temsili) dökmek için kullanılır. Bu onun kullanım durumu.


"Promise dönen işlevler, eşzamansız olarak atabilecekleri için genellikle eşzamanlı olarak atmamaları gerektiğine dair garantiye sahip olmalıdır". Neden işlevlerin eşzamanlı veya eşzamansız olması gerektiğini, ancak her ikisinin birden olmaması gerektiğini açıklayabilir misiniz? Şu anda Promise.resolve () 'dan hoşlanıyorum. Kullanmanın Promise.resolve()bir anti-pattern olduğunu söyleyecek kadar ileri gider misiniz ?
Ashley Coolman

2
@AshleyCoolman bakınız blog.izs.me/post/59142742143/designing-apis-for-asynchrony - bazen zaman uyumsuz olarak davranan bir yöntem tutarlılık için her zaman bunu yapmalıdır .
Benjamin Gruenbaum

İle aynı şekilde Promise.resolve()yeni bir örnek Promiseoluşturuyor newmu? Aksi return Promise.resolve(yourCode)takdirde daha hızlı olur ve senkronize atışlardan kaçınır.
Steven Vachon

1
Kendimi kötü hissediyorum, hatanın reddedilmiş bir söz haline geldiğinden emin olmak için "Promise.resolve (). Sonra (function () {/ * bir hataya neden olabilecek durum * /}). Sonra ..." kullanıyorum ... "Promise.method" konusuna daha fazla bakacağım
Polopollo

1
@ Polopollo veya Promise.coroutinehangisi daha kullanışlı.
Benjamin Gruenbaum

18

Yukarıdaki cevaplarda veya yorumlarda belirtilmeyen başka bir fark daha var:

Eğer bir someObjectise Promise, new Promise(resolve)iki ek kene mal olur.


Aşağıdaki iki kod parçacığını karşılaştırın:

const p = new Promise(resovle => setTimeout(resovle));

new Promise(resolve => resolve(p)).then(() => {
  console.log("tick 3");
});

p.then(() => {
  console.log("tick 1");
}).then(() => {
  console.log("tick 2");
});

const p = new Promise(resovle => setTimeout(resovle));

Promise.resolve(p).then(() => {
  console.log("tick 3");
});

p.then(() => {
  console.log("tick 1");
}).then(() => {
  console.log("tick 2");
});

İkinci pasaj, ilk olarak '3'ü işaretleyin' yazdırır. Neden?

  • Değer bir söz ise, Promise.resolve(value)değeri tam olarak döndürür. Promise.resolve(value) === valuedoğru olurdu. MDN'ye bakın

  • Ancak new Promise(resolve => resolve(value)), verilen valuesözü yerine getirmek için kilitlenen yeni bir söz verecekti . 'Kilitlemeyi' yapmak için fazladan bir işarete ihtiyaç vardır.

    // something like:
    addToMicroTaskQueue(() => {
      p.then(() => {
        /* resolve newly promise */
      })
        // all subsequent .then on newly promise go on from here
        .then(() => {
          console.log("tick 3");
        });
    });
    

    tick 1 .thenÇağrı ilk aday olacağını.


Referanslar:

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.