Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
429 views
in Technique[技术] by (71.8m points)

for循环中不修改timeout值, 每隔1秒输出

很简单的一个需求, 循环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)
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

新的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);
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share

1.2m questions

2.1m answers

5 comments

56.5k users

...