美文网首页
promise大厂面试真题总结

promise大厂面试真题总结

作者: 刷题刷到手抽筋 | 来源:发表于2022-05-23 07:53 被阅读0次

    我在网上搜索大厂面经,总结了一些promise的经典面试题。希望能帮助到需要的同学。
    更多题目,可以访问灵题库

    关于promise的“说出代码执行结果”的面试题解题思路,可以参考我的另一篇文章:
    一文讲透Promise面试题:说出代码执行结果

    1. 说出代码执行结果(百度)

    题目

    说出下面代码执行结果

    const promise = new Promise((resolve,reject)=>{
        console.log(1);
        resolve();
        console.log(2);
        reject()
    })
    setTimeout(()=>{console.log(5)},0)
    promise.then(()=>{console.log(3)})
    .then(()=>{console.log(6)})
    .catch(()=>{console.log(7)})
    console.log(4)
    

    答案

    答案是1,2,4,3,6,5
    首先new Promise时候打印1和2,因为new Promise时候会立即执行传入的方法
    然后后面代码都是异步代码,先将setTimeout的回调加入宏任务队列,再把promise.then放入到微任务队列,然后直接执行最后一句,打印4
    这样宏任务代码执行完了,接下来开始执行微任务队列中的任务,由于promise resolve,因为promise resolve之后状态不会再改变,因此不会执行到reject的对调,所以打印3和6
    微任务队列为空,再到宏任务队列中查找任务,找到setTimeout回调执行,打印5
    调用栈、宏任务队列、微任务队列都为空,代码执行结束。

    2. 说出代码执行结果(阿里)

    题目

    说出下面代码执行结果

    const first = () => (new Promise((resolve, reject) => {
        console.log(3);
        let p = new Promise((resolve, reject) => {
            console.log(7);
            setTimeout(() => {
                console.log(5);
                resolve();
            }, 0);
            resolve(1);
        });
        resolve(2);
        p.then((arg) => {
            console.log(arg);
        });
    }));
    first().then((arg) => {
        console.log(arg);
    });
    console.log(4);
    

    答案

    3, 7, 4, 1, 2, 5
    首先定义first
    然后执行first,然后执行new Promise传入的方法,先打印3
    又new Promise,执行其中传入的方法,打印7
    执行setTimeout,将回调放入宏任务队列
    执行resolve(1),将内部promise状态置为fullfilled,值为1
    执行resolve(2),将外部promise状态置为fullfilled,值为2
    执行内部promise.then方法,将回调加入微任务队列
    执行first().then,即外部的promise,将回调加入到微任务队列
    调用栈为空,开始从微任务队列拿取任务,首先拿到内部promise的回调,打印其值1
    然后从微任务队列中拿取外部的promise的回调,打印其值2
    此时微任务队列为空,开始从宏任务队列中拿取任务,即setTimeout回调,打印5。
    调用栈,宏任务队列和微任务队列都为空,执行结束。

    3. 说出代码执行结果(字节)

    题目

    说出下面代码执行结果

    console.log(1);
    new Promise(resolve => {
        resolve();
        console.log(2);
    }).then(() => {
        console.log(3);
    })
    setTimeout(() => {
        console.log(4);
    }, 0);
    console.log(5);
    

    答案

    1,2,5,3,4
    先打印1
    执行new Promise的函数,打印2
    执行promise.then,将回调加入微任务队列
    将setTimeout的回调加入宏任务队列
    打印5
    调用栈为空,取微任务队列中的任务执行,打印3
    微任务队列为空,取宏任务队列任务执行,打印5
    调用栈、微任务队列、宏任务队列都为空,执行结束

    4. 说出代码执行结果(字节)

    题目

    说出下面代码执行结果

    Promise.resolve()
    .then(() => {
        console.log('1');
    })
    .then(() => {
        console.log('2');
    });
    
    
    setTimeout(() => {
        Promise.resolve()
        .then(() => {
            console.log('3');
        })
        .then(() => {
            console.log('4');
        });
        setInterval(() => {
            console.log('5');
        }, 3000);
        console.log('6');
    }, 0);
    

    答案

    1,2,6,3,4,5,5...
    先执行Promise.resolve,将两个回调加入到微任务队列中
    执行setTimeout,将其回调加入宏任务队列
    调用栈为空,拿出微任务队列中的两个回调执行,打印1,2
    微任务队列为空,拿出宏任务队列中的setTimeout的回调执行
    将setTimeout中的Promise.resolve的两个回调加入到微任务队列
    将setTimeout中的setInterval的回调加入宏任务队列
    打印6
    取出微任务队列中的两个Promise的回调,打印3,4
    取宏任务队列中的setInterval的回调执行,每隔3s符合执行条件,打印5。注意setInterval调用时候不马上会执行一次,第一次执行是3s以后。

    5. 说出代码执行结果(网易)

    题目

    说出代码执行结果

    setTimeout(function() {
        console.log(1);
    }, 0);
    console.log(2);
    async function s1() {
        console.log(7)
        await s2();
        console.log(8);
    }
    asycn function s2() {
        console.log(9);
    }
    s1();
    new Promise((resolve, reject) => {
        console.log(3);
        resolve();
        console.log(6);
    }).then(() => console.log(4))
    console.log(5);
    

    答案

    2,7,9,3,6,5,8,4,1
    记住async只是promise的语法糖,转化为等价的形式就好分析了
    先执行setTimeout,加入宏任务队列中
    打印2
    执行s1,同步打印7
    执行s2,同步打印3
    执行完s2,将console.log(8)加入到微任务队列
    然后执行s1后面的Promise,打印3和6
    执行then,将console.log(4)加入到微任务队列中
    打印5
    调用栈为空,将微任务队列中的两个任务依次拿出来执行,打印8和4
    微任务队列执行完,将宏任务队列的任务拿出来执行,打印1
    调用栈、微任务队列、宏任务队列都为空,执行完毕。

    6. 代码的执行结果(拼多多)

    题目

    说出下面代码执行结果

    function fn() {
      return new Promise((resolve, reject) => {
          setTimeout(() => {
              reject('error');
          }, 1000);
      });
    }
    const foo = async () => {
       try {
         await fn();
      } catch (e) {
          console.log('lala', e);  // some error
      }
    }
    foo();
    

    答案

    打印 lala error。
    如果await后面返回的promise reject掉,需要用try catch语句捕获这个reject。

    7. 讲讲promise(字节、美团、拼多多)

    题目

    讲讲promise,promise的3种状态和状态转换。
    Promise中回调函数是同步的还是异步的?then的链式调用是同步的还是异步的?

    答案

    promise目的:异步编程解决回调地狱,让程序开发者编写的异步代码具有更好的可读性。
    promise规范规定了一种异步编程解决方案的API。规范规定了promise对象的状态和then方法。
    promise是这种异步编程的解决方案的具体实现。

    new Promise对象时候传入函数,函数立即执行,函数接收resolve、reject参数,调用resolve或reject时候会改变promise状态。状态改变后不会再变化。
    promise状态

    • pending
    • fullfilled
    • rejected
      未调用resolve或者reject时候处于pending状态,调用resolve后处于fullfilled状态,调用reject后处于rejected状态。如果在pending状态时候,执行任务抛出错误,则变成reject状态。
      状态变化后,会执行通过then注册的回调。执行顺序和调用then方法的顺序相同。
      调用then方法时候,如果状态是pending则注册回调,等到状态改变时候执行,如果状态已经改变则执行相应的回调。

    Promise回调函数是同步的,then回调是异步的,会被放到微任务队列中异步执行。

    8. 手写promise(百度、拼多多、京东)

    题目

    手写promise

    答案

    参考这篇文章:
    手写Promise

    9. 实现Promise.all,Promise.race,Promise.any(百度、滴滴、网易)

    题目

    如何实现Promise.all、Promise.race和Promise.any方法。

    答案

    Promise.all,Promise.race,Promise.any的实现

    function all(arr) {
        return new Promise((resolve, reject) => {
            let isComplete = false;
            const resolveDataList = new Array(arr.length).fill(undefined);
            const onFullfilled = (data, i) => {
                if (isComplete) {
                    return;
                }
                resolveDataList[i] = data;
                if (resolveDataList.every(item => item !== undefined)) {
                    resolve(resolveDataList);
                }
            };
            const onRejected = reason => {
                if (isComplete) {
                    return;
                }
                isComplete = true;
                reject(reason);
            }
            arr.forEach((promise, index) => {
                promise.then(
                    data => {onFullfilled(data, index)},
                    onRejected
                );
            });
        });
    }
    
    
    function race(arr) {
        return new Promise((resolve, reject) => {
            let isComplete = false;
            const onFullfilled = data => {
                if (isComplete) {
                    return;
                }
                isComplete = true;
                resolve(data);
            };
            const onRejected = reason => {
                if (isComplete) {
                    return;
                }
                isComplete = true;
                reject(reason);
            };
            arr.forEach(promise => {
                promise.then(
                    onFullfilled, onRejected
                );
            });
        });
    }
    
    function any(arr) {
        return new Promise((resolve, reject) => {
            let isComplete = false;
            const rejectDataList = new Array(arr.length).fill(undefined);
            const onFullfilled = data => {
                if (isComplete) {
                    return;
                }
                isComplete = true;
                resolve(data);
            };
            const onRejected = (reason, i) => {
                if (isComplete) {
                    return;
                }
                rejectDataList[i] = reason;
                if (rejectDataList.every(item => item !== undefined)) {
                    reject('AggregateError: All promises were rejected');
                }
            }
            arr.forEach((promise, index) => {
                promise.then(
                    onFullfilled,
                    reason => {onRejected(reason, index);}
                );
            });
        });
    }
    

    10. Promise.all,Promise.race区别(拼多多)

    题目

    Promise.all,Promise.race区别是什么?
    手写一个方法,使用Promise.all,实现所有都resolved/reject时才返回,并返回所有的结果

    答案

    区别是:
    Promise.all() 全部promise成功才算成功,一个promise就算失败,成功的话,返回成功的数据数组,失败的话抛出最先失败的promise的reason。
    Promise.race() 最先的promise完成则返回,promise结果和最先完成的promise一致。

    手写方法:

    function allComplete(arr) {
        return Promise.all(arr.map(promise => {
            return new Promise(
                resolve => promise.then(resolve, resolve)
            );
        }));
    }
    

    关注「灵题库」,更多大厂面试真题解析。

    相关文章

      网友评论

          本文标题:promise大厂面试真题总结

          本文链接:https://www.haomeiwen.com/subject/gofmurtx.html