【面试题】Promise只会概念远远不够,还需这17道题目巩固!_前端面试题 promise(1)

}, 0)
console.log(4)
// 4 1 3 2

* **当宏任务嵌套微任务时**:

 

// 宏任务嵌套微任务
setTimeout(() => {
console.log(1);
// 微任务
Promise.resolve().then(() => {
console.log(2)
})
}, 0)
setTimeout(() => {
console.log(3)
}, 0)
console.log(4)
// 4 1 2 3

* **微任务嵌套微任务时**:同层级微任务优先执行。因为任务队列先入队都是同级别的。

 

// 微任务链接微任务
Promise.resolve().then(() => {
console.log(1)
return 2;
}).then((res) => {
console.log(res);
})
Promise.resolve().then(() => {
console.log(3)
})
// 1 3 2

// 微任务嵌套微任务
Promise.resolve().then(() => {
console.log(1)
Promise.resolve().then(() => {
console.log(2)
})
return 3
}).then((res) => {
console.log(res);
})
Promise.resolve().then(() => {
console.log(4)
})
// 1 4 2 3



**题目5️⃣:结合微任务和宏任务,灵活理解Promise三种状态**。从代码中我们可以看出例子中的单纯是同步任务有2 3 4,而宏任务中的同步任务是1,当执行程序中同步任务时,微任务还没有resolve回调函数,所以promise对象都是pending状态,由于抛出错误是微任务中的宏任务,所以优先执行,然后再执行全局的setTimeout,最后promise1是fufilled状态,promise2是rejected状态。



const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(“success”);
console.log(1);
}, 1000);
console.log(2);
});
const promise2 = promise1.then(() => {
throw new Error(“error!!!”);
});
console.log(3, promise1);// pending
console.log(4, promise2);// pending
setTimeout(() => {
console.log(5);
console.log(6, promise1);// fufilled
console.log(7, promise2);// rejected
}, 2000);
// 2 3 4 1 抛出error! 5 6 7


**题目6️⃣:Promise中构造函数中的resolve或reject只有第一次执行有效。**



const promise = new Promise((resolve, reject) => {
resolve(1);
reject(“error”);
resolve(2);
});
promise.then(res => {
console.log("then: ", res);
}).catch(err => {
console.log("catch: ", err);
})
// then:1


**题目7️⃣:Promise对象中的catch无视链接位置,都能捕获上层未捕捉过的错误**,then3会执行因为catch会返回一个Promise,且由于这个Promise没有返回值,所以打印出来的是undefined。



const promise = new Promise((resolve, reject) => {
reject(“error”);
resolve(1);
});
promise.then(res => {
console.log("then1: ", res);
}).then(res => {
console.log("then2: ", res);
}).catch(err => {
console.log("catch: ", err);
}).then(res => {
console.log("then3: ", res);
})
// catch: error
// then3: undefined


**题目8️⃣:Promise对象的链式调用的执行顺序**。Promise可以链式调用,不过promise 每次调用 .then 或者 .catch 都会返回一个新的 promise,从而实现了链式调用,return 2会被包装为resolve(2)。



Promise.resolve(1)
.then(res => {
console.log(res);
return 2;
})
.catch(err => {
return 3;
})
.then(res => {
console.log(res);
});
// 1 2


**题目9️⃣:注意then的第二参数错误处理与catch的区别。**,两个都是处理reject状态回调结果或者是抛出的错误,如果存在第二参数,也存在catch,捕获错误是参数生效,否则就会catch生效。也可以这样理解then的第一个参数是处理成功的函数,第二个参数是处理失败的函数。如果两个都没有就会直接报错。



Promise.reject(‘err!!!’)
.then((res) => {
console.log(‘success’, res)
}, (err) => {
console.log(‘error’, err)
}).catch(err => {
console.log(‘catch’, err)
})
// error err!!!

Promise.resolve()
.then(() => {
throw new Error(‘error!!!’);
})
.then(
function success(res) {},
function fail1(err) {
console.log(‘fail1’, err);
}
)
.catch(function fail2(err) {
console.log(‘fail2’, err);
});
// fail1 Error: error!!!


**题目🔟:then参数是函数,对于非函数会出现值穿透。** 如果then传入的是非函数,resolve会被传到是函数的地方。



Promise.resolve(1).then(2).then(Promise.resolve(3))
.then(console.log)
// 1


**题目1️⃣1️⃣:finally方法也是一个微任务。**:.finally()方法不管Promise对象最后的状态如何都会执行。.finally()方法的回调函数不接受任何的参数。



function promise1() {
let p = new Promise((resolve) => {
console.log(1);
resolve(2)
})
return p;
}
function promise2() {
return new Promise((resolve, reject) => {
reject(‘error’)
})
}
promise1()
.then(res => console.log(res))
.catch(err => console.log(err))
.finally(() => console.log(‘finally1’))

promise2()
.then(res => console.log(res))
.catch(err => console.log(err))
.finally(() => console.log(‘finally2’))
// 1 2 error finally1 finally2


**题目1️⃣2️⃣:async await执行机制**:在async1中await后面的Promise是没有返回值的,也就是它的状态始终是pending状态,因此相当于一直在await,await,await却始终没有响应,所以就不能执行await后面的语句了。


* **async await宏任务**:await强制的是当前async函数域,所以不能优先处理await后面的语句,全局同步任务可优先处理。

 

async function async1() {
console.log(1);
await async2();
console.log(2);
}
async function async2() {
setTimeout(() => {
console.log(3)
}, 0)
console.log(4);
}
async1();
console.log(5)
// 1 4 5 2 3

* **async await微任务**:

 

async function async1() {
console.log(1);
await new Promise(resolve => {
console.log(2)
})
// Promise没有resolve所以一直处于pending
console.log(3);
return ‘async1 end’
}
console.log(4)
async1().then(res => console.log(res))
console.log(5)
// 4 1 2 5

* **async await微任务、宏任务**:

 

async function testSometing() {
console.log(1);
return 2;
}
async function testAsync() {
console.log(3);
return Promise.resolve(4);
}
async function test() {
console.log(5);
const v1 = await testSometing();
console.log(v1);
const v2 = await testAsync();
console.log(v2);
console.log(v1, v2);
}
test();
var promise = new Promise(resolve => {
console.log(6);
resolve(7);
});
promise.then(val => console.log(val));
console.log(8);
// 5 1 6 8 2 3 7 4
// 2 4



**题目1️⃣3️⃣:理解Promise.all方法**,all方需要等所有异步操作执行完后才执行回调,由于有reject状态的回调,所以没有执行then,直接执行了catch。



function runAsync(x) {
const p = new Promise(r => setTimeout(() => r(x, console.log(‘runAsync’, x)), 1000))
return p
}
function runReject(x) {
const p = new Promise((res, rej) => setTimeout(() => rej(Error: ${x}, console.log(‘runRejct’, x)), 1000 * x))
return p
}
Promise.all([runAsync(1), runReject(4), runAsync(3), runReject(2)])
.then(res => console.log(‘then:’, res))
.catch(err => console.log(‘catch:’, err))
// runAsync 1
// runAsync 3
// runRejct 2
// catch: Error: 2
// runRejct 4


**问题1️⃣4️⃣:理解Promise.race方法**,race获取最快的哪一个异步操作的结果。由于下面执行了一个reject状态的回调,所以没有执行then,如果没有这个runReject(0),下面例子打印的是1 result:1 2 3。



function runAsync(x) {
const p = new Promise(r =>
setTimeout(() => r(x, console.log(x)), 1000)
);
return p;
}
function runReject(x) {
const p = new Promise((res, rej) =>
setTimeout(() => rej(Error: ${x}, console.log(x)), 1000 * x)
);
return p;
}
Promise.race([runReject(0), runAsync(1), runAsync(2), runAsync(3)])
.then(res => console.log("result: ", res))
.catch(err => console.log(err));
// 0 Error:0 1 2 3


**问题1️⃣5️⃣:** 构造函数里resolve之前的同步任务打印3 7优先执行,然后就是first后面的全局同步任务4,注意这里与上面的嵌套微任务的区别,因为这里直接resolve(2)的话first就会完成回调函数了,但是最外层构造函数内还有一个微任务p,所以先执行。



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

更多面试题

**《350页前端校招面试题精编解析大全》**内容大纲主要包括 HTML,CSS,前端基础,前端核心,前端进阶,移动端开发,计算机基础,算法与数据结构,项目,职业发展等等

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

      resolve(1);
    });
    resolve(2);
    p.then((arg) => {
            console.log(arg);
    });

更多面试题

**《350页前端校招面试题精编解析大全》**内容大纲主要包括 HTML,CSS,前端基础,前端核心,前端进阶,移动端开发,计算机基础,算法与数据结构,项目,职业发展等等

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

[外链图片转存中…(img-tyYnIEj8-1714510519296)]

  • 11
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值