首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有可能继续暂停异步函数?(2)

是否有可能继续暂停异步函数?(2)
EN

Stack Overflow用户
提问于 2017-12-07 12:39:03
回答 3查看 97关注 0票数 0

我在前面的代码中做了一些修改,运行了更多的测试,并且再次遇到了同样的问题(Is it possible continue a stopped async function?)。所以这个问题是相关的。

此外,以前的解决方案不起作用。

代码语言:javascript
复制
var stop = false;
var pause = false;
var elParrafo = document.getElementById('miParrafo');

function sendPause() {
  pause = true;
}

function sendContinue() {
  pause = false;
}

function sendStop() {
  stop = true;
}

function longWork(ms, char) {
  return new Promise(function(resolve, reject) {
    elParrafo.innerHTML += char;
    setTimeout(resolve, ms);
  });
}

async function doIt() {
  for (var i = 0; i < 666; i++) {
    if (!stop) {
      if (!pause) {
        await longWork(50," > ");
      }
    } else {
      break;
    }
  }
}

doIt();
代码语言:javascript
复制
<form class="" action="index.html" method="post">
  <input type="button" value="Pause" onclick="sendPause()">
  <input type="button" value="Continue" onclick="sendContinue()">
  <input type="button" value="Stop" onclick="sendStop()">
</form>
<p id="miParrafo"></p>

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-12-07 12:56:25

当您将标志设置为true时,会发生此问题。在取消设置标志时,异步代码会耗尽循环的其余部分。你可以用一些承诺来逃避它。

代码语言:javascript
复制
let stop = false;
let isPaused = false;
let resolvePause = () => {};
let pauseProm = Promise.resolve();
const elParrafo = document.getElementById('miParrafo');

function sendPause() {
  if(isPaused) return;

  isPaused = true;
  pauseProm = new Promise(resolve => resolvePause = resolve);
}

function sendContinue() {
  isPaused = false;
  resolvePause();
}

function sendStop() {
  stop = true;
}

function longWork(ms, char) {
  return new Promise(function(resolve, reject) {
    elParrafo.innerHTML += char;
    setTimeout(resolve, ms);
  });
}

async function doIt() {
  for (let i = 0; i < 666; i++) {
    if (stop) break;

    await pauseProm;
    await longWork(50," > ");
  }
}

doIt();
代码语言:javascript
复制
<form class="" action="index.html" method="post">
  <input type="button" value="Pause" onclick="sendPause()">
  <input type="button" value="Continue" onclick="sendContinue()">
  <input type="button" value="Stop" onclick="sendStop()">
</form>
<p id="miParrafo"></p>

票数 3
EN

Stack Overflow用户

发布于 2017-12-07 12:57:00

当您暂停任务时,您实际上必须暂停它并等待直到用户想要继续,而不是继续循环到结束,但不做任何工作。

代码语言:javascript
复制
var stopped;
var paused;
var waitingContinuations;

function sendStart() {
  stopped = false;
  paused = false;
  waitingContinuations = [];
  doIt();
}

function sendPause() {
  paused = true;
}

function sendContinue() {
  paused = false;
  for (const cont of waitingContinuations)
    cont();
  waitingContinuations.length = 0;
}

function sendStop() {
  stopped = true;
}

async function doIt() {
  document.getElementById('output').textContent = "";
  for (var i = 0; i < 666; i++) {
    // in places where you might want to abort, put this:
    if (stopped) return; // or throw new Error("stopped");
    // in places where you might want to pause, put this:
    if (paused) await new Promise(resolve => waitingContinuations.push(resolve));

    await longWork(50, " > ");
  }
}

function longWork(ms, char) {
  return new Promise(resolve => {
    document.getElementById('output').textContent += char;
    setTimeout(resolve, ms);
  });
}
代码语言:javascript
复制
<form>
  <input type="button" value="Start" onclick="sendStart()">
  <input type="button" value="Pause" onclick="sendPause()">
  <input type="button" value="Continue" onclick="sendContinue()">
  <input type="button" value="Stop" onclick="sendStop()">
</form>
<p id="output"></p>

票数 4
EN

Stack Overflow用户

发布于 2017-12-07 14:57:27

下面是一个使用setInterval的简单解决方案:

代码语言:javascript
复制
var task = (function(){
  var timer;
  var taskImplementation;
  var max;
  var ms;
  var timesRun = 0;
  var isPaused = false;
  const runTask = function(){
    if(!isPaused && timesRun<max){
      taskImplementation();
      timesRun++;
    }else{
      clearInterval(timer);
    }
  };
  const reset = function() {
    timesRun=0;
    isPaused=false;    
  };
  const start = function(){
    if(timer){
      stop();
    }
    reset();
    timer = setInterval(runTask,ms);
  };
  const stop = function(){
    reset();
    clearInterval(timer);
  };
  const pause = function(){
    clearTimeout(timer);
  };
  const cont = function(){
    timer = setInterval(runTask,ms);    
  };
  return function(doWhat){
    taskImplementation = doWhat;
    return function(interval){
      ms = interval;
      return function(howManyTimes){
        max = howManyTimes;        
        return {
          start:start,
          stop:stop,
          pause:pause,
          continue:cont
        }
      }
    }
  }
})();
var doWhat = (function(elParrafo){
  return function(){
    elParrafo.innerHTML += " > ";
  }
})(document.getElementById('miParrafo'));
var interval =200;//how long to wait between task execution
var howManyTimes = 666;//how many times to repeat task
window.setParrafoTask = task(doWhat)(interval)(howManyTimes);
代码语言:javascript
复制
    <form class="" action="index.html" method="post">
        <input type="button" value="Start" onclick="setParrafoTask.start()">
        <input type="button" value="Pause" onclick="setParrafoTask.pause()">
        <input type="button" value="Continue" onclick="setParrafoTask.continue()">
        <input type="button" value="Stop" onclick="setParrafoTask.stop()">
      </form>
      <p id="miParrafo"></p>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47695364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档