es6面试题--Promise相关
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