我在之前的代码中进行了一些更改,运行了更多测试,并且我再次遇到了同样的问题(Is it possible continue a stopped async function?)。所以这个问题是相关的。
此外,之前的解决方案不起作用。
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();
&#13;
<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>
&#13;
答案 0 :(得分:4)
当你暂停任务时,你必须实际暂停它并等到用户想要继续,不要继续你的循环直到结束但没有做任何工作。
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);
});
}
<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>
答案 1 :(得分:3)
将flags设置为true时会出现此问题。在取消设置标志时,异步代码会耗尽循环的其余部分。你可以用一些承诺绕过它。
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();
<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>
答案 2 :(得分:0)
这是一个使用setInterval的简单解决方案:
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);
&#13;
<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>
&#13;