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里面的函數才會被推入微任務中;