簡體   English   中英

已解決的承諾等待內部承諾被解決

[英]Resolved promise waits for inner promise to be resolved

我想要一個許諾,像這樣:

let first = new Promise(resolveFirst => {
    setTimeout(() => {
        resolveFirst("resolved!");
    }, 2000)
});

let second = new Promise(resolveSecond => {
    setTimeout(() => {
        resolveSecond(first);
    }, 10)
});

second.then(secondValue => {
    console.log("second value: ", secondValue);
    secondValue.then(firstValue => {
        console.log("first value: ", firstValue);
    });
});

這樣console.log("second value: ", secondValue); 10毫秒后打印,然后console.log("first value: ", firstValue)將打印2000

雖然發生了什么,但是我得到了:

第二個價值:解決!

還有一個錯誤:

未捕獲(承諾)TypeError:secondValue.then不是函數

2010之后的千禧年。

看來,當第二個諾言得到解決,並且第一個諾言被返回時,它也會自動等待第一個諾言得到解決。

這是為什么? 我該如何在它們之間休息?


編輯

這是使用Array.reduce()在Facebook上發布的解決方案:

const runPromisesInSeries = 
    ps => ps.reduce((p, next) => 
        p.then(next), Promise.resolve());

const delay = d => new Promise(r => setTimeout(r, d));
runPromisesInSeries([() => delay(1000), () => delay(2000)]);
//executes each promise sequentially, taking a total of 3 seconds to complete

https://www.facebook.com/addyosmaniofficial/photos/a.10151435123819601.1073741825.129712729600/10155386805609601/?type=3&theater

通過設計,用第二個承諾解決的承諾將承擔第二個承諾的履行(履行或拒絕)之后第二個承諾的價值和狀態,並根據需要等待其履行。

除非promise庫存在嚴重缺陷(舊版本的JQuery會使用其他庫中的promise對象來實現自己的promise對象),否則不可能用promise或thenable對象(任何具有then方法的對象)值來實現promise )。

諾言拒絕沒有相同的檢查,並且會很樂意將諾言對象傳遞到鏈下而無需等待其解決。 因此,您可以拒絕第一個諾言的第二個諾言,並在catch子句中選擇它。

盡管從技術上講我是可行的,但我強烈建議您不要這樣做,除非證明它可以做到-對於試圖理解代碼的第三方來說,這是一個維護問題。

盡管您可以將諾言作為對象屬性傳遞到諾言鏈的成功渠道下,但對諾言組成的重新分析可能會提供更好或更標准的解決方案。 EG Promise.all在繼續執行一項共同任務之前,等待兩個或多個獨立的諾言得以兌現。

那只是他們魅力的一部分:如果您的諾言A決定了可以成立的B,那么A僅在B決定解決后才解決,而A則采用B的決定價值。 這是Promises / A +ES6的一部分,是“承諾解決程序”的一部分。

如果(例如)一個操作需要在完成之前執行一個操作(例如登錄),或者需要加載另一頁結果,或者具有自己的重試邏輯,則可以看到其中的一些優點。

盡管不是很習慣,但是如果您不等待而立即返回未解決的承諾,則可以通過將其傳遞到{object}[array] ,但是這樣做的理由可能不多:除了等待為完成它,您將如何處理已兌現的承諾?

你可以連續使用then只有一個承諾。 secondValue不是一個諾言,它只是您調用second諾言時返回的值。 或該承諾的resolved價值。

如果您希望該方法起作用,請嘗試以下操作:

let first = new Promise(resolveFirst => {
  setTimeout(() => {
    resolveFirst("resolved!");
  }, 2000)
});

let second = new Promise(resolveSecond => {
  setTimeout(() => {
    resolveSecond(first);
  }, 10)
});

second.then(secondValue => {
    console.log("second value: ", secondValue);
    /** first is a Promise. return a promise, and the next "then"
     * will pass the result of that Promise.
     */
    return first
  })
  .then(firstValue => {
    console.log(firstValue)
  })

編輯1

為什么進一步解釋second承諾解決的最終值( string中的) first承諾,而不是承諾本身, 可以在MDN中找到:

Promise.resolve()

如果值是一個承諾,則該對象成為對Promise.resolve的調用的結果; 否則,返回的承諾將被履行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM