提问人:Rocko 提问时间:11/9/2023 最后编辑:DavidRocko 更新时间:11/9/2023 访问量:66
JS程序如何知道函数内部setTimeout中的时间?[复制]
how JS program knows the time in setTimeout inside a function? [duplicate]
问:
const p1 = new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("xxx");
}, 5000)
});
const p2 = new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("xx");
}, 10000)
});
async function he() {
console.log("start");
const s1 = await p1;
console.log("Rome");
const s2 = await p2;
console.log("Paris");
}
he();
console.log("Hey bro")
问题 - 现在,当程序执行开始时,它会立即打印“start”,然后打印“hey bro”,JS 不会等待等待完成并继续执行。现在,当 JS 在 he() 中遇到 p1 时,它会在 5 秒后打印“Rome”,然后在接下来的 5 秒后打印 Paris。
现在我的问题是,为什么它在 10 秒后没有打印巴黎?p2 的计时器是如何在达到 p2 初始化之前启动的?或者是吗?我知道当它遇到 p1 时,它会停止在调用堆栈中执行 he() func,这是它以某种方式开始在幕后执行 s2 的时候吗?
答:
0赞
Alexander Nied
11/9/2023
#1
因为它是异步的,而你没有 ing .你不能在顶层,但如果你把整个程序嵌套在一个函数中,你可以看到它的行为符合我相信你的期望。await
he()
await
async
await
he()
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("xxx");
}, 5000)
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("xx");
}, 10000)
});
async function he() {
console.log("start");
const s1 = await p1;
console.log("Rome");
const s2 = await p2;
console.log("Paris");
}
async function runProgram() {
await he();
console.log("Hey bro")
}
runProgram();
此外,值得注意的是,您不是在调用,而是 - 它们是在您分配它们的那一刻开始倒计时的承诺,因此即使您没有调用,它们也会在初始化和分配后的几秒钟内解析。p1
p2
he()
5
10
评论
0赞
Rocko
11/9/2023
你能回答我这个问题吗?“但据我所知,也许一旦程序遇到 await 的承诺,它就会从 callstack 中删除该函数!所以,这就是为什么当遇到 p1 时,它会立即打印“嘿兄弟”,但是如果我学到的是正确的,那么 p2 的执行是如何在 p1 结束之前开始的呢?Becz func 本身不在调用堆栈中”
0赞
Alexander Nied
11/9/2023
@Rocko我不确定我是否完全理解您的问题,但您似乎对开始第一次超时后如何继续执行感到困惑。我认为你在两个方面感到困惑:1)你实际上并没有调用,而且 - 你在定义它们的那一刻就启动了它们的计时器,因为这就是你编写它的方式,以及 2)尽管 JS 可能不是多线程的,但它仍然能够异步执行,并且诸如此类的事情的全部目的是允许执行不受限制地继续执行,同时等待执行传递给的内容(除非您)。p1
p2
setTimeout
setTimeout
await
1赞
David
11/9/2023
#2
p2 的计时器是如何在达到 p2 初始化之前启动的?
当你这样做时,它没有开始:
const s2 = await p2;
当您执行此操作时,它就开始了:
const p2 = new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("xx");
}, 10000)
});
也就是说,两个计时器/承诺都立即启动。你在函数中所做的就是等待这些承诺的结果,但它们已经开始了。he
第一个计时器是 5 秒,第二个计时器是 10 秒。它们同时启动并同时运行。
你可以通过不定义承诺来实现你正在寻找的结果,直到你想等待它们。例如:
async function he() {
console.log("start");
const s1 = await new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("xxx");
}, 5000)
});
console.log("Rome");
const s2 = await new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("xx");
}, 10000)
});;
console.log("Paris");
}
he();
console.log("Hey bro")
或者通过定义创建/返回 promise 的函数,而不是定义 promise 本身:
const p1 = () => new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("xxx");
}, 5000)
});
const p2 = () => new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("xx");
}, 10000)
});
async function he() {
console.log("start");
const s1 = await p1();
console.log("Rome");
const s2 = await p2();
console.log("Paris");
}
he();
console.log("Hey bro")
评论
Now my question is, why didn't it print Paris after 10 sec?
出于同样的原因,你看到的是 - 异步调用没有阻塞,因此下一个函数调用会立即发生。hey bro
start
const p1 = new Promise(...
const p1 = () => new Promise(...
p2
await p1
await p1()
new Promise()
p2
const p1 = new Promise()
const p2 = new Promise()
await p1
setTimeout()