我正在编写一个简短的程序来了解 JavaScript 中的 Promises。
该程序的目标是将数字列表(从 5 减少到 0)打印到 HTML 页面上,每个数字之间有 0.5 秒的延迟。打印 0 后,会弹出一个确认框,允许用户再次打印相同的数字或停止。
目前,下面的代码大部分都在工作,但在内部循环(在countdown()函数中)的第一次和第二次迭代期间,它的行为非常奇怪——在打印第一次5和4.
我在 chrome dev 中对其进行了很多调试,试图弄清楚发生了什么,所以我在代码部分下面包含了一个关于程序实际在做什么(或似乎在做什么)的分步指南,用粗体表示的奇怪行为。
这是一个没有标记的大学作业,我设法难倒了我的教授,所以非常感谢任何帮助。提前致谢!!
// wait time for setTimeout
var wait = 500;
function timer(ms) {
return new Promise((res) => {
setTimeout(res, ms);
});
}
async function countdown() {
for (let i = 5; i >= 0; i--) {
document.write("<br>");
document.write(i);
console.log(i);
await timer(wait).then();
}
var c = confirm("Do you want to go again?");
document.write("<br>User Confirm:");
document.write(c);
console.log(c);
return c;
}
async function repeatRun() {
var prom = new Promise(async(res, rej) => {
r = await countdown();
if (r) {
res();
} else {
rej();
}
});
prom.then(
data => {
document.write("<br>RERUN");
console.log("RERUN");
repeatRun();
},
error => {
document.write("<br>ENDED");
console.log("ENDED");
}
);
}
repeatRun();
<!DOCTYPE html>
<html>
<head>
<title>Countdown</title>
</head>
<body>
<h1>Countdown</h1>
<p>Internet Applications Ex1.</p>
</body>
</html>
这是我的程序一步一步做的事情:
显示 HTML 页面标题等
进入
script标签进入
repeatRun()创建 Promise 变量
prom并输入countdown()循环的第一次迭代
for(即i=5)5.1。prints
<br>和5usingdocument.write(),两者都附加到 HTML 正文中5.2. 进入
timer()5.3. 返回
new Promise5.4. 这个承诺返回到
prom.then()内部repeatRun()而不是await timer()像我预期的那样调用之后我尝试过这个有和没有
.then(),它做同样的事情[这发生在 Chrome 调试器上的一步]退出
script标签重新进入
script标签,但不是从头开始:它返回for循环并减少i当前的 HTML 文件:
<html> <head> <title>Countdown</title> </head> <body> <h1>Countdown</h1> <p>Internet Applications Ex1.</p> <script>...</scri pt> <br> "5" </body> </html>下一个 document.write() 调用,而不是附加
<br>到 HTML 正文,用 替换旧的 HTML 正文<br>,head标记也被删除下一个 document.write() 将(现在为 4)附加
i到新的 HTML 文件当前的 HTML 文件中:<html> <head></head> <body> <br> "4" </body>
这是程序开始按预期运行的地方 10. 进入
timer()函数,然后返回countdown()11. 按预期循环直到i=0
11.1. `document.write()` appends to HTML body instead of rewriting
11.2. `timer()` function is called and returns to `countdown()` function afterwards
- 在这个循环之后,弹出确认窗口:我点击“确定”并
true存储在c,打印使用document.write(),返回并存储在r - 因为
r=true,if成功并被res()调用 - 输入
prom.then()然后data =>并正确document.write附加"<br>RERUN"到 HTML 正文 - 该
repeatRun()函数被递归调用 - 创建新的 promise var 并调用
countdown() - 这一次,
for循环按预期发生(即在步骤 11 中)从i=5到i=0 - 循环结束后,我在确认窗口中点击“取消”,
c设置为false,打印,返回并存储在r - 因为
r=false,if失败并被rej()调用 - 输入
prom.then()然后error =>和 document.write 正确附加"<br>ENDED"到 HTML 正文 - 退出
script标签