是否可以在Javascript中链接setTimeout函数?

xia*_*ica 16 javascript

是否可以链接setTimout函数以确保它们相继运行?

谢谢你

jfr*_*d00 42

当然.当第一个发射时,只需设置下一个.

setTimeout(function() {
    // do something
    setTimeout(function() {
        // do second thing
    }, 1000);
}, 1000);
Run Code Online (Sandbox Code Playgroud)

你也可以让自己成为一个小实用程序对象,它可以让你真正地链接一些可以让你像这样链接调用的东西:

delay(fn1, 400).delay(fn2, 500).delay(fn3, 800);
Run Code Online (Sandbox Code Playgroud)

function delay(fn, t) {
    // private instance variables
    var queue = [], self, timer;
    
    function schedule(fn, t) {
        timer = setTimeout(function() {
            timer = null;
            fn();
            if (queue.length) {
                var item = queue.shift();
                schedule(item.fn, item.t);
            }
        }, t);            
    }
    self = {
        delay: function(fn, t) {
            // if already queuing things or running a timer, 
            //   then just add to the queue
        	  if (queue.length || timer) {
                queue.push({fn: fn, t: t});
            } else {
                // no queue or timer yet, so schedule the timer
                schedule(fn, t);
            }
            return self;
        },
        cancel: function() {
            clearTimeout(timer);
            queue = [];
            return self;
        }
    };
    return self.delay(fn, t);
}

function log(args) {
    var str = "";
    for (var i = 0; i < arguments.length; i++) {
        if (typeof arguments[i] === "object") {
            str += JSON.stringify(arguments[i]);
        } else {
            str += arguments[i];
        }
    }
    var div = document.createElement("div");
    div.innerHTML = str;
    var target = log.id ? document.getElementById(log.id) : document.body;
    target.appendChild(div);
}


function log1() {
	  log("Message 1");
}
function log2() {
	  log("Message 2");
}
function log3() {
	  log("Message 3");
}

var d = delay(log1, 500)
    .delay(log2, 700)
    .delay(log3, 600)
Run Code Online (Sandbox Code Playgroud)

或者,既然它现在是ES6 +中承诺的时代,那么使用promises的类似代码我们让promise基础设施为我们排队和排序:

Promise.delay(fn1, 500).delay(fn2, 700).delay(fn3, 600);
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,绑定是甜蜜的,工作.对于任何有兴趣的人来说,https://jsfiddle.net/efbbrown/ypa25gsc/1/是如何将输入绑定到fn参数的. (2认同)

小智 6

async对于 ES6,使用/非常简单await。这也很容易阅读,并且对承诺答案进行了一些升级。

// Expect to be async
    async function timePush(...arr){
        function delay(t){
            return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                    resolve();
                },t)
            })
        }
        // for the length of this array run a delay
        // then log, you could always use a callback here
        for(let i of arr){
            //pass the items delay to delay function
            await delay(i.time);
            console.log(i.text)
        }
    }
    
    
    timePush(
        {time:1000,text:'hey'},
        {time:5000,text:'you'},
        {time:1000,text:'guys'}
    );
Run Code Online (Sandbox Code Playgroud)


Pen*_*Liu 5

受到@jfriend00 的启发,我演示了一个较短的版本:

Promise.resolve()
  .then(() => delay(400))
  .then(() => log1())
  .then(() => delay(500))
  .then(() => log2())
  .then(() => delay(800))
  .then(() => log3());

function delay(duration) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(), duration);
  });
}

function log1() {
  console.log("Message 1");
}

function log2() {
  console.log("Message 2");
}

function log3() {
  console.log("Message 3");
}
Run Code Online (Sandbox Code Playgroud)