緣起
小編最近在刷題,看到了手寫一個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中處理,提升了可讀性和寫代碼的愉悅性
尾聲
小編不得不吐槽一句,自己想到很多問題,逼着自己去思考,雖然過程會很痛苦,但是一旦你思考完畢,你對這塊的理解就會更加深入!寫代碼還是要多思考,越思考大腦纔會轉的越快!