最慢之后重复功能:上一个功能完成,或者x秒已经过去

时间:2017-09-08 14:38:14

标签: javascript node.js setinterval

假设我有一个异步函数inconsistentDurationAsync,它可能需要花费任何时间来完成,可能不到一分钟,但通常在0秒到30秒之间。我无法预测该功能需要多长时间才能完成。

我希望每timeout毫秒运行此函数,但前提是它已经完成。

如果还没有完成,我想等到它完成再重新打电话。

此刻我的代码尽可能简单地简化,只是一个

setInterval(inconsistentDurationAsync, timeout);

但很明显,在再次调用之前,它不会检查功能是否已完成。

4 个答案:

答案 0 :(得分:0)

您可以使用简单的final ImageView url = (ImageView) findViewById(R.id.imageView); buttonLoad = (Button) findViewById(R.id.buttonLoad); buttonLoad.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Picasso.with(this).load("http://test.please.do/app/car.jpg").into(url); } }); 标志,每当调用该方法时,将其设置为active,完成后将其设置为true。如果在调用false时已经true,请使用inconsistentDurationAsync来突破该功能。

return

答案 1 :(得分:0)

首先,我将描述此问题的常见范例,这适用于任何语言:

  • minInterval设置为最小任务执行间隔
  • 请将当前时间记为startTime
  • 开始你的长任务
  • 任务完成后,计算remainingTime = minInterval - (currentTime - startTime)
  • IFF remainingTime > 0以时间单位等待remainingTime
  • 返回第1步。

Node.js示例(假设您正在使用某些Promise实现,例如bluebird:

// In node you might need: const Promise = require("bluebird")
    const MIN_INTERVAL = 4*1000;

    if(!Promise.delay) {
        Promise.delay = function(duration) {
            return new Promise((res,rej)=>setTimeout(res, duration));
        };
    }
    function getRandomInt(min, max) {
      return Math.floor(Math.random() * (max - min + 1)) + min;
    }
    async function inconsistentDurationAsync() {
        await Promise.delay(getRandomInt(100, 10*1000));
    }
    var shouldDoStuff = true;
    async function doStuff() {
        while(shouldDoStuff) {
            const startTime = new Date().getTime();
            await inconsistentDurationAsync();
            const duration = new Date().getTime() - startTime;
            const remainingTime = MIN_INTERVAL - duration;
            if(remainingTime>0)
                await Promise.delay(remainingTime);
            console.log("Done. Duration: ", duration,"ms; Sleep: ", Math.max(0, remainingTime), "ms");
            if(document && document.body) {
                var div = document.createElement("div")
                div.appendChild(new Text("Done. Duration: "+ duration+"ms; Sleep: "+ Math.max(0, remainingTime)+ "ms"));
                document.body.appendChild(div);
            
            }
        }
    }
    doStuff();

答案 2 :(得分:0)

这是一个使用两个承诺的解决方案:

  • 一个具有最小间隔持续时间。这个承诺将在经过一段时间后实现。它取代了setTimeout
  • 只要持续时间未知的任务完成,另一个承诺就会实现。

只有两个承诺都得到满足才会重新开始。



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

function minDurationPromise() {
  console.log('Starting min duration promise of 3000ms');
  // Return the async task with a 3000ms duration, log a message once it is done.
  return asyncTask(3000).then(() => console.log('min duration lapsed'));
}

function randomDurationPromise() {
  const
    // Create a random duration for the async task.
    randomDuration = Math.floor(Math.random() * 4000) + 1000;
  
  console.log(`Starting random duration promise of ${randomDuration}ms`);
  // Return the async task with a random duration, log a message once it is done.
  return asyncTask(randomDuration).then(() => console.log('random duration lapsed'));
}

function doSomething() {
  console.log('Starting both promises');
  // Wait for both async tasks to be completed...
  Promise.all([minDurationPromise(), randomDurationPromise()])
    .then(() => {
      // ... when both are done log a message...
      console.log('both promise fullfilled');
      // ...and start again.
      doSomething();
    });
}

doSomething();




答案 3 :(得分:0)

你的函数的每个终点都需要有setTimeout。 承诺不符合这个目标。

function inconsistentDurationAsync()
{
    function doneCallback()
    {
        // complete your last callback in the chain
        setTimeout(inconsistentDurationAsync, timeout);
    }
}