最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端面试之异步任务顺序化(async/await)

    正文概述 掘金(白天的蓝云)   2021-04-07   590

    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)
    	})
    

    输出结果如下

    前端面试之异步任务顺序化(async/await) 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/await)

    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('结束')
    }
    
    1. 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.总结

    这个问题更多是在考查我们对各种循环的底层实现的理解,不过关键在于异步任务的耗时大小和正确执行顺序的矛盾。在面试中我们先需要把握矛盾,沿着正确的思路出发。

    本人大三,正寻实习,与君共勉。寥有拙作,万望指正


    起源地下载网 » 前端面试之异步任务顺序化(async/await)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元