關於promise的實現原理的思考

緣起


小編最近在刷題,看到了手寫一個promise的文章,小編突然產生了幾個問題

  • promsie本身有沒有暫停js進程功能
  • promise是如何實現把值傳入then中的
  • promsie把值傳入then中的時候,爲啥會先執行promise以外的函數

promise實現

這裏小編不具體寫代碼了,小編寫個大概的就好,想看詳細的大家可以去google搜索

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function Promise(executor) {
	let self = this;
    self.status = PENDING;
     function resolve(value) {
        if (self.status === PENDING) {
            self.status = FULFILLED;
            self.value = value;
        }
    }
  // reject代碼此處省略
    try {
        executor(resolve, reject);
    } catch (e) {
        reject(e);
    }
}

Promise.prototype.then = function (onFulfilled, onRejected) {
    let self = this;
    let promise2 = new Promise((resolve, reject) => {
    	if (self.status === FULFILLED) {
            setTimeout(() => {
                try {
                  onFulfilled(self.value);
                } catch (e) {
                    reject(e);
                }
            });
        }
    }
}

以上就是一個簡單版本的promise,雖然省略了很多代碼,但是主要就是定義一個名爲promise的構造函數,在其原型鏈上擴展then方法,把new Promise需要傳遞下去的值,放在原型鏈上,then可以通過原型鏈獲得,重點來了,利用了原型鏈,就這麼簡單!

解答上面的問題


  • promsie本身有沒有暫停js進程功能
    大家可以看上面的代碼,promise本身不存在停止js運行功能!能暫停js運行的方法目前有以下幾種:ajax的同步,await,生成器函數!說白了這個就是基於瀏覽器(c,c++,c#等)中斷了單線程的js任務進程,迫使等待某個函數執行完畢!
  • promise是如何實現把值傳入then中的
    這個問題上面已經回答了,就是利用了原型鏈,從原型鏈獲取值
  • promsie把值傳入then中的時候,爲啥會先執行promise以外的函數,大家看到then中的那個定時器了嘛,可以去惡補下宏任務和微任務!

看圖再次理解


在這裏插入圖片描述
如果promise本身具有中斷js進程的功能,那麼3出現的位置不會是1後面!因爲then中的定時器所以,輸出的順序是4和2!

業務代碼加深理解


// xx.js
console.log('start')
new Promise((resolve, reject) => {
	// await 操作,再resolve()
}).then(v=>{})
console.log('end)

代碼運行的時候,js的單線程會先輸出start,然後promise運行到await停止,這個時候總線程是不會停止的,停止的只是await等待返回的那部分代碼執行,總線程接着執行end,然後等到await返回的時候,線程再切到await那塊,然後再執行resolve(),這就是我們看到的等待執行,then處理!
爲啥在await等待的時候,不直接執行then呢,這裏有一個很重要的概念,鏈式調用!
鏈式調用只會按照順序來,如果前面等待,那麼後面的方法會等待前面的執行完畢,纔會調用
這個時候有的童鞋可能要問了,既然promise本身沒法中斷js代碼執行,讓頁面等待,都是用了回調函數中的await等方式,那麼promise的優勢有啥?

promise的優勢


  • 保證了js單線程不會因爲await等中斷,充分利用了瀏覽器性能
  • 鏈式調用和then方法保證了相關代碼在then中處理,提升了可讀性和寫代碼的愉悅性

尾聲


小編不得不吐槽一句,自己想到很多問題,逼着自己去思考,雖然過程會很痛苦,但是一旦你思考完畢,你對這塊的理解就會更加深入!寫代碼還是要多思考,越思考大腦纔會轉的越快!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章