Promise.resolve()與new Promise(r => r(v))


Promise.resolve方法的參數分成四種情況。

參數是一個 Promise 實例

如果參數是 Promise 實例,那么Promise.resolve將不做任何修改、原封不動地返回這個實例。
這是一個特殊的情況會和另一種new Promise(r => r(v))產生不一樣的效果,最后說明

參數是一個thenable對象

thenable對象指的是具有then方法的對象,比如下面這個對象

let thenable = {
  then: function(resolve, reject) {
    resolve(42);
  }
};

Promise.resolve方法會將這個對象轉為 Promise 對象,然后就立即執行thenable對象的then方法。

let thenable = {
  then: function(resolve, reject) {
    resolve(42);
  }
};

let p1 = Promise.resolve(thenable);
p1.then(function(value) {
  console.log(value);  // 42
});

thenable對象的then方法執行后,對象p1的狀態就變為resolved,從而立即執行最后那個then方法指定的回調函數,輸出 42

參數不是具有then方法的對象,或根本就不是對象

如果參數是一個原始值,或者是一個不具有then方法的對象,則Promise.resolve方法返回一個新的 Promise 對象,狀態為resolved。

const p = Promise.resolve('Hello');

p.then(function (s){
  console.log(s)
});
// Hello

由於字符串Hello不屬於異步操作(判斷方法是字符串對象不具有 then 方法),返回 Promise 實例的狀態從一生成就是resolved,所以回調函數會執行。Promise.resolve方法的參數,會同時傳給回調函數

不帶有任何參數

Promise.resolve方法允許調用時不帶參數,直接返回一個resolved狀態的 Promise 對象。

setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');

// one
// two
// three

.then()函數里不返回值或者返回的不是promise,那么 then 返回的 Promise 將會成為接受狀態(resolve)

Promise.resolve().then(() => console.log(2)).then(() => console.log(3));
console.log(1); // 1, 2, 3

需要注意的是,立即resolve的 Promise 對象,是在本輪“事件循環”(event loop)的結束時執行執行,不是馬上執行,也不是在下一輪“事件循環”的開始時執行
原因:傳遞到 then() 中的函數被置入了一個微任務隊列,而不是立即執行,這意味着它是在 JavaScript 事件隊列的所有運行時結束了,事件隊列被清空之后,才開始執行

Promise.resolve(v)不等於new Promise(r => r(v))

當v是一個Promise實例的時候就會出現一些不同的地方

    // v是一個實例化的promise,且狀態為fulfilled
    let v = new Promise(resolve => {
      console.log("begin");
      resolve("then");
    });

    // 在promise里面resolve一個狀態為fulfilled的promise

    // 模式一 new Promise里的resolve()
    // begin->1->2->3->then->4 可以發現then推遲了兩個時序
    // 推遲原因:瀏覽器會創建一個 PromiseResolveThenableJob 去處理這個 Promise 實例,這是一個微任務。
    // 等到下次循環到來這個微任務會執行,也就是PromiseResolveThenableJob 執行中的時候,因為這個Promise 實例是fulfilled狀態,所以又會注冊一個它的.then()回調
    // 又等一次循環到這個Promise 實例它的.then()回調執行后,才會注冊下面的這個.then(),於是就被推遲了兩個時序
    new Promise(resolve => {
      resolve(v);
    }).then((v)=>{
        console.log(v)
    });

    //  模式二 Promise.resolve(v)直接創建
    // begin->1->then->2->3->4 可以發現then的執行時間正常了,第一個執行的微任務就是下面這個.then
    // 原因:Promise.resolve()API如果參數是promise會直接返回這個promise實例,不會做任何處理
/*     Promise.resolve(v).then((v)=>{
        console.log(v)
    }); */

    new Promise(resolve => {
      console.log(1);
      resolve();
    })
      .then(() => {
        console.log(2);
      })
      .then(() => {
        console.log(3);
      })
      .then(() => {
        console.log(4);
      });

resolve()本質作用

  • resolve()是用來表示promise的狀態為fullfilled,相當於只是定義了一個有狀態的Promise,但是並沒有調用它;
  • promise調用then的前提是promise的狀態為fullfilled;
  • 只有promise調用then的時候,then里面的函數才會被推入微任務中;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM