1、
const promise = new Promise((resolve, reject) => { console.log(1); resolve(); console.log(2); }); promise.then(() => { console.log(3); }); console.log(4);
輸出結果為:1,2,4,3。
解題思路:then方法是異步執行的。
2、
const promise = new Promise((resolve, reject) => { setTimeout(() => { resolve('success') reject('error') }, 1000) }) promise.then((res)=>{ console.log(res) },(err)=>{ console.log(err) })
輸出結果:success
解題思路:Promise狀態一旦改變,無法在發生變更。
3、
Promise.resolve(1) .then(2) .then(Promise.resolve(3)) .then(console.log)
輸出結果:1
解題思路:Promise的then方法的參數期望是函數,傳入非函數則會發生值穿透。
4、
setTimeout(()=>{ console.log('setTimeout') }) let p1 = new Promise((resolve)=>{ console.log('Promise1') resolve('Promise2') }) p1.then((res)=>{ console.log(res) }) console.log(1)
輸出結果:
Promise1
1
Promise2
setTimeout
解題思路:這個牽扯到js的執行隊列問題,整個script代碼,放在了macrotask queue中,執行到setTimeout時會新建一個macrotask queue。但是,promise.then放到了另一個任務隊列microtask queue中。script的執行引擎會取1個macrotask queue中的task,執行之。然后把所有microtask queue順序執行完,再取setTimeout所在的macrotask queue按順序開始執行。(具體參考https://www.zhihu.com/question/36972010)
5、
Promise.resolve(1) .then((res) => { console.log(res); return 2; }) .catch((err) => { return 3; }) .then((res) => { console.log(res); });
輸出結果:1 2
解題思路:Promise首先resolve(1),接着就會執行then函數,因此會輸出1,然后在函數中返回2。因為是resolve函數,因此后面的catch函數不會執行,而是直接執行第二個then函數,因此會輸出2。
6、
const promise = new Promise((resolve, reject) => { setTimeout(() => { console.log('開始'); resolve('success'); }, 5000); }); const start = Date.now(); promise.then((res) => { console.log(res, Date.now() - start); }); promise.then((res) => { console.log(res, Date.now() - start); });
輸出結果:
開始
success 5002
success 5002
解題思路:promise 的.then
或者.catch
可以被調用多次,但這里 Promise 構造函數只執行一次。或者說 promise 內部狀態一經改變,並且有了一個值,那么后續每次調用.then
或者.catch
都會直接拿到該值。
7、
let p1 = new Promise((resolve,reject)=>{ let num = 6 if(num<5){ console.log('resolve1') resolve(num) }else{ console.log('reject1') reject(num) } }) p1.then((res)=>{ console.log('resolve2') console.log(res) },(rej)=>{ console.log('reject2') let p2 = new Promise((resolve,reject)=>{ if(rej*2>10){ console.log('resolve3') resolve(rej*2) }else{ console.log('reject3') reject(rej*2) } }) return p2 }).then((res)=>{ console.log('resolve4') console.log(res) },(rej)=>{ console.log('reject4') console.log(rej) })
輸出結果:
reject1
reject2
resolve3
resolve4
12
解題思路:我們上面說了Promise的先進之處在於可以在then方法中繼續寫Promise對象並返回。
8、實現一個簡單的promise
function Promise(fn){ var status = 'pending' function successNotify(){ status = 'fulfilled'//狀態變為fulfilled toDoThen.apply(undefined, arguments)//執行回調 } function failNotify(){ status = 'rejected'//狀態變為rejected toDoThen.apply(undefined, arguments)//執行回調 } function toDoThen(){ setTimeout(()=>{ // 保證回調是異步執行的 if(status === 'fulfilled'){ for(let i =0; i< successArray.length;i ++) { successArray[i].apply(undefined, arguments)//執行then里面的回掉函數 } }else if(status === 'rejected'){ for(let i =0; i< failArray.length;i ++) { failArray[i].apply(undefined, arguments)//執行then里面的回掉函數 } } }) } var successArray = [] var failArray = [] fn.call(undefined, successNotify, failNotify) return { then: function(successFn, failFn){ successArray.push(successFn) failArray.push(failFn) return undefined // 此處應該返回一個Promise } } }
解題思路:Promise中的resolve和reject用於改變Promise的狀態和傳參,then中的參數必須是作為回調執行的函數。因此,當Promise改變狀態之后會調用回調函數,根據狀態的不同選擇需要執行的回調函數。
轉自:https://www.cnblogs.com/lunlunshiwo/archive/2018/04/16/8852984.html