javascript - for循环中不修改timeout值, 每隔1秒输出
PHPz
PHPz 2017-04-11 13:00:15
[JavaScript讨论组]

很简单的一个需求, 循环10次, 每隔1秒输出i的值, 伪代码如下

for(let i=0; i<10; i++) {
    setTimeout(function(){
        console.log(i)
    }, 1000)
}

地球人都知道这样会都输出一个值

用闭包可以实现1秒后输出所有值, 但是我想要的是每隔1秒输出一个值(不用改变timeout的时间, 比如:(i+1)*1000, 这种方式)

请问:这个如何实现?

补充一个@李引证的答案, 估计好多同学看的不太懂

  • 这段代码在node里面是运行不通的, 因为需要es7, 可以在浏览器里面运行

  • const sleep = time=>new Promise(resolve=>setTimeout(resolve,time));这段代码简写的很严重, 我改成详版

const sleep = (time) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve()
        }, time)
    })
}

这样看的能清楚些

  • 其实这些sleep函数真的没干么事, 方法如其名, 只是sleep了一段时间

  • 其实await是有返回值的, 返回的是resolve的参数, 不信你试试这段代码

async function test() {
    for (let i = 0; i < 10; i++) {
        let t = await sleep(1000)
        console.log(t, i)
    }
}
PHPz
PHPz

学习是最好的投资!

全部回复(6)
伊谢尔伦

新的async/await语法可以轻松实现。

const sleep = time=>new Promise(resolve=>setTimeout(resolve,time));
(async function(){
   for(let i=0;i<10;i++){
       await sleep(1000);
       console.log(i);
   }
})()

如果要只想用ES6的话,也可以的,用生成器yield代替,并且写个自动run的辅助函数。

const next = (gen,val) => {
     const n = gen.next(val);
     !n.done && Promise.resolve(n.value).then(d=>next(gen,d));
 }
const run = genfunc => next(genfunc());
const sleep = time=>new Promise(resolve=>setTimeout(resolve,time));
run(function* (){
    for(let i=0;i<10;i++){
       yield sleep(1000);
       console.log(i);
    } 
})

如果是ES5的话,只能创造一个数组,然后在异步函数里不停的调用next来传递顺序,常用node的人应该对express的next不陌生吧。

function run(arr,func){
   var len = arr.length;
   function next(){
      if(!len) return;
      func(arr[arr.length-len],next);
      len--;
   }
   next();
}
var arr = Array.apply(null, {length: 10}).map(Function.call, Number);
run(arr,function(i,next){
   setTimeout(function(){
       console.log(i);
       next();
   },1000);
});
天蓬老师

for(let i=0; i<10; i++) {

setTimeout(function(){
    console.log(i)
}, i*1000)

}

怪我咯
for(let i=0; i<10; i++) {
    (function(j) {
        setTimeout(function(){
            console.log(j);
        }, j*1000)
    })(i);
}

这样可以?

PHP中文网

用setInterval

巴扎黑

嵌套执行setTimeout即可

var arr = Array.from({length: 10}).map((ele, index) => index)
var nexttimeout = () => setTimeout(() => { console.log(arr.pop()); arr.length && nexttimeout()}, 1000)
nexttimeout()
巴扎黑
let i = 0;

function foo (num) {
  setTimeout(function(){
        console.log(num);
        if (num < 10) { 
          foo(num + 1);
        }
    }, 1000)
}

foo(0);

案例

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号