1.引言
前端面试关于异步实现的问题有很多,中心相近,侧重不一,难度参差。细节颇多。其中一类为它的顺序化,例:考题场景为:在常用的循环中用实现await可能产生的问题,如何选择循环,理由是
async function test() {
let arr = [6, 5, 8]
/*
设计循环输出arr[6,5,8]
*/
console.log('结束')
}
function handle(x) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(x)
}, 2000 * x)
})
}
test()
2.测试
1.错误答案forEach()
。使用它并不能使输出按照数组元素顺序输出,数字的顺序依据Promise的setTimeOut
设置的时间升序.有时候程序的多个任务执行需要遵循一定顺序,但任务花费的时间不同。这样的处理会产生问题。
arr.forEach(async item => {
const res = await handle(item)
console.log(res)
})
输出结果如下
2.问题的原因:在forEach的底层实现中可以找到问题。forEach 拿过来直接执行了,这就导致它无法保证异步任务的执行顺序。由于循环执行一遍的时间远远少于Promise中耗时任务的执行时间,耗时少的数字下标先被判断,先执行回调函数,先输出
for (var i = 0; i < length; i++) {
if (i in array) {
var element = array[i];
callback(element, i, array);//回调函数接受三个参数,当前的值,下标,数组名来执行
}
}
3.正确答案for of
。输出如我们所愿
async function test() {
let arr = [6, 5, 8]
for(const item of arr) {
const res = await handle(item)
console.log(res)
}
console.log('结束')
}
4.成功的原因:Iterator(迭代器),for of 采用迭代器遍历数组,原生具有[Symbol.iterator]属性数据类型为可迭代数据类型。如数组、类数组(如arguments、NodeList)、Set和Map。如码可知,Symbol.iterator为数组每项添加了额外属性,value和done;后者是保证成功的核心。通过判断done(是否完成),配合迭代器的next()
方法决定是否执行数组的下一任务。
let arr = [6, 5, 8];
// 这就是迭代器
let iterator = arr[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
// {value: 4, done: false}
// {value: 2, done: false}
// {value: 1, done: false}
// {value: undefined, done: true}
所以for of相当于以下代码
async function test() {
let arr = [6, 5, 8]
let iterator = arr[Symbol.iterator]();
let res = iterator.next();
while(!res.done) {//循环的条件是当前任务未完成
let value = res.value;
console.log(value);
await handle(value);
res = iterater.next();//当值被await handle(处理)时,才开启下个任务,保证顺序
}
console.log('结束')
}
for in
for in遍历数组的毛病
1.index索引为字符串型数字,不能直接进行几何运算
2.遍历顺序有可能不是按照实际数组的内部顺序
3.使用for in会遍历数组所有的可枚举属性,包括原型。
所以for in更适合遍历对象,不要使用for in遍历数组。但它也可以达到目的。只需稍稍改变。原理和for of
相似。
for(const item in arr) {
const res = await handle(arr[item])
console.log(res)
}
3.总结
这个问题更多是在考查我们对各种循环的底层实现的理解,不过关键在于异步任务的耗时大小和正确执行顺序的矛盾。在面试中我们先需要把握矛盾,沿着正确的思路出发。
本人大三,正寻实习,与君共勉。寥有拙作,万望指正
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!