现在很多前端小伙伴太过注重各类框架的学习,各类第三方包的使用;但是冷落了好些开发最重要的前端基础。没有基础,怎能建成高楼大厦呢?会些基本的node、php、python后端语言,mysql、mongodb数据库,会用些后端框架,模板解析框架,写些api,文件系统操作等,然后动不动就把全栈挂在嘴巴上,这样做意义好像真心不大。学习是一个不断重复的过程,基础知识一个需要不断回顾的过程,一切的框架第三方库都是基于原生实现,多看源代码,努力学好原生,跑遍天下浏览器不卡壳;从今天起,坚持每隔一两天总结些比较有趣的原生JS的小练习,多多练习回顾下。
1.for循环配合setTimeout
(1)解决下面的输出问题,想要得到的结果为:0 1 2 3 4 5
function a(i){
console.log(i); // 5 5 5 5 5
}
for (var i = 0; i < 5; i++) {
setTimeout(function(){
a(i);
},1000);
}
解决办法:
function a(i){
setTimeout(function(){
console.log(i)
},1000);
}
for (var i = 0; i < 5; i++) {
a(i);
}
(2)for循环同时开启5个定时器
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(new Date, i);
}, 2000);
}
console.log(new Date, i);
//打印如下:
/*
demo.html:17 Thu Nov 15 2018 11:11:21 GMT+0800 (中国标准时间) 5
demo.html:13 Thu Nov 15 2018 11:11:23 GMT+0800 (中国标准时间) 5
demo.html:13 Thu Nov 15 2018 11:11:23 GMT+0800 (中国标准时间) 5
demo.html:13 Thu Nov 15 2018 11:11:23 GMT+0800 (中国标准时间) 5
demo.html:13 Thu Nov 15 2018 11:11:23 GMT+0800 (中国标准时间) 5
demo.html:13 Thu Nov 15 2018 11:11:23 GMT+0800 (中国标准时间) 5
*/
(3)解决上面的问题,希望可以输出 5 -> 0 1 2 3 4 5
1-3-1. 闭包解决
for (var i = 0; i < 5; i++) {
(function(j) {
setTimeout(function() {
console.log(new Date, j);
},1000);
})(i);
}
console.log(new Date, i);
//打印如下:
/*
demo.html:19 Thu Nov 15 2018 11:22:00 GMT+0800 (中国标准时间) 5
demo.html:14 Thu Nov 15 2018 11:22:01 GMT+0800 (中国标准时间) 0
demo.html:14 Thu Nov 15 2018 11:22:01 GMT+0800 (中国标准时间) 1
demo.html:14 Thu Nov 15 2018 11:22:01 GMT+0800 (中国标准时间) 2
demo.html:14 Thu Nov 15 2018 11:22:01 GMT+0800 (中国标准时间) 3
demo.html:14 Thu Nov 15 2018 11:22:01 GMT+0800 (中国标准时间) 4
*/
1-3-2. 使用let
let i = 0;
for (; i < 5; i++) {
setTimeout(function() {
console.log(new Date, i);
},1000);
}
console.log(new Date, i);
2. 优化上面的代码需要异步输出: 0 1 2 3 4 5
(1)第一种方法
for (var i = 0; i < 5; i++) {
~function(i){
setTimeout(function() {
console.log(new Date, i);
}, 1000);
}(i)
}
setTimeout(function(){
console.log(new Date, i);
},1000)
//打印如下:
/*
demo.html:21 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 0
demo.html:21 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 1
demo.html:21 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 2
demo.html:21 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 3
demo.html:21 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 4
demo.html:27 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 5
*/
(2)第二种需求每隔1s输出:0 1 2 3 4 5,使用es6中的Promise解决方案
const tasks = [];
for (var i = 0; i < 5; i++) {
tasks.push(new Promise((resolve,reject)=>{
(function(i){
setTimeout(() => {
console.log(new Date, i);
resolve();
}, 1000*i)
})(i)
}))
}
Promise.all(tasks).then(() => {
setTimeout(() => {
console.log(new Date, i);
}, 1000);
})
//打印如下:
/*
Thu Nov 15 2018 14:03:16 GMT+0800 (中国标准时间) 0
demo.html:23 Thu Nov 15 2018 14:03:17 GMT+0800 (中国标准时间) 1
demo.html:23 Thu Nov 15 2018 14:03:18 GMT+0800 (中国标准时间) 2
demo.html:23 Thu Nov 15 2018 14:03:19 GMT+0800 (中国标准时间) 3
demo.html:23 Thu Nov 15 2018 14:03:20 GMT+0800 (中国标准时间) 4
demo.html:34 Thu Nov 15 2018 14:03:21 GMT+0800 (中国标准时间) 5
*/
(3)使用ES7中的async和await处理上诉问题,每隔1s输出 0 1 2 3 4 5
function sleep(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, time);
} )
}
async function timeout() {
for(var i = 0;i<5; i++){
await sleep(1000);
console.log(new Date,i);
}
await sleep(1000);
console.log(new Date, i);
return '结束';
}
timeout().then(res => {
console.log(new Date,res);
})
// 打印结果如下:
/*
demo.html:24 Thu Nov 15 2018 14:30:12 GMT+0800 (中国标准时间) 0
demo.html:24 Thu Nov 15 2018 14:30:13 GMT+0800 (中国标准时间) 1
demo.html:24 Thu Nov 15 2018 14:30:14 GMT+0800 (中国标准时间) 2
demo.html:24 Thu Nov 15 2018 14:30:15 GMT+0800 (中国标准时间) 3
demo.html:24 Thu Nov 15 2018 14:30:16 GMT+0800 (中国标准时间) 4
demo.html:27 Thu Nov 15 2018 14:30:17 GMT+0800 (中国标准时间) 5
demo.html:33 Thu Nov 15 2018 14:30:17 GMT+0800 (中国标准时间) "结束"
*/