课程视频--循环中调用异步方法html
最近遇到一道比较有趣的面试题,题目很简单可是涉及到了不少小的知识点,还蛮有意思的。前端
一个普通的for循环输出ies6
// 正常写一个for循环输出i for (var i = 0; i < 5; i++) { console.log(i); } console.log(i);
假设你是一个面试者,你说说这几行代码会输出什么?,你的心里活动会不会是“这特么不就是一个循环吗?面试官既然这么问老子(他还笑确定不是好东西,确定有陷阱),好好想一下,这好像和我看的那个闭包的题很像啊,这面试官是否是没写完啊?怎么办。”面试
若是稍微改动一些尼,输出结果又是什么?ajax
for循环中有一个定时器segmentfault
for (var i = 0; i < 5; i++) { setTimeout(function () { console.log(new Date, i); }1000 * i); } console.log(new Date, i);
稍微加了点料(setTimeout)后,是否是看到这道题就舒服了,会不会想“’这不是老子背的最多的闭包问题么,想一哈,setTimeout是会延迟执行的因此外面的log会先执行,i是用var声明的,因此会变量提高,for循环里i最后执行完i++,i变成了5,没错了,老子这题得分了”。promise
闭包解决。闭包
// 闭包 for (var i = 0; i < 5; i++) { ~function (j) { setTimeout(function () { console.log(new Date, j); }, 1000 * j); }(i); }
顺着上一个程式想“是否是还能够升华一下,我还能执行出来0 1 2 3 4”异步
实做async
var roles = ['角色1', '角色2', '角色3']; var arrayTest = []; for (var i = 0; i < roles.length; i++) { !function (i) { $.get('https://www.baidu.com', { role: roles[i] }, function (res) { console.log(i); arrayTest[i] = i + roles[i] + res; }) }(i); }
若是你登陆一个后台系统,这个帐号下有不一样角色(角色不固定,后期可能增长),传不一样角色进行ajax请求获得相应渲染页面的数据,可是这个接口只接收一个角色参数, 那咱们应该怎么按咱们想要的顺序获取数据而后渲染页面?
es6
const tasks = []; for (var i = 0; i < 5; i++) { ((j) => { tasks.push(new Promise((resolve) => { setTimeout(() => { console.log(new Date, j); resolve(); }, 1000 * j); // 定时器的超时时间逐步增长 })); })(i); } Promise.all(tasks).then(() => { setTimeout(() => { console.log(new Date, i); }, 1000); });
当你前面全部问题都顺利的回答完了,你想没想过可能还有20%的人能够回答到你这种程度,怎么能变现的比他们牛逼一点尼?你能够考虑使用一下promise
setTimeout和promise优先级
setTimeout(function () { console.log(1) }, 0); new Promise(function executor(resolve) { console.log(2); for (var i = 0; i < 10000; i++) { i == 9999 && resolve(); } console.log(3); }).then(function () { console.log(4); }); console.log(5);
“这道题应该考察我 JavaScript 的运行机制的,让我理一下思路。
首先先碰到一个 setTimeout,因而会先设置一个定时,在定时结束后将传递这个函数放到任务队列里面,所以开始确定不会输出 1 。
而后是一个 Promise,里面的函数是直接执行的,所以应该直接输出 2 3 。
而后,Promise 的 then 应当会放到当前 tick 的最后,可是仍是在当前 tick 中。
所以,应当先输出 5,而后再输出 4 。
最后在到下一个 tick,就是 1 。
“2 3 5 4 1”
es7
const sleep = (timeountMS) => new Promise((resolve) => { setTimeout(resolve, timeountMS); }); (async () => { // 声明即执行的 async 函数表达式 for (var i = 0; i < 5; i++) { await sleep(1000); console.log(new Date, i); } await sleep(1000); console.log(new Date, i); })();
要是想给面试官留一个关注新技术的更牛逼印象,那就用es7说一下吧。
原始高清视频下载
QQ答疑交流群:
600633658
咱们的连接: