promise大厂面试真题总结

我在网上搜索大厂面经,总结了一些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)
        );
    }));
}

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容