我面临着困惑,希望得到一些澄清或参考文章来解释以下代码片段中观察到的行为。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise Resolved Value!!");
}, 20000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise Resolved Value!!");
}, 10000);
});
async function handlePromise() {
try {
console.log("Hello World!!");
const val = await p1;
console.log("Namaste JavaScript");
console.log(val);
const val2 = await p2;
console.log("Namaste JavaScript 2");
console.log(val2);
} catch (error) {
console.error("Error:", error);
}
}
handlePromise();
在这种情况下,程序会打印“Hello World!!”然后等待20秒。等待期结束后,p1 和 p2 部分将同时打印。我试图理解为什么两个承诺同时执行。
但是
对于这段代码
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise Resolved Value!!");
}, 10000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise Resolved Value!!");
}, 20000);
});
async function handlePromise() {
try {
console.log("Hello World!!");
const val = await p1;
console.log("Namaste JavaScript");
console.log(val);
const val2 = await p2;
console.log("Namaste JavaScript 2");
console.log(val2);
} catch (error) {
console.error("Error:", error);
}
}
handlePromise();
在这种情况下,打印“Hello World!!”后,程序在延迟 20 秒后打印 p1 部分,然后在延迟 10 秒后打印 p2 部分。我正在寻求对这种特定计时行为的解释。
任何解释 JavaScript Promise 底层异步性质的文章的见解或参考都会非常有帮助。谢谢!
试图寻求对多重承诺、异步等待行为的解释
请务必记住,
await
不会阻止 javascript 解释器。当您等待时,其他事情仍然可能发生,并且其他代码片段仍然可以在您等待的事件完成之前执行。 await
关键字只会阻止您的功能。
首先,两种情况是相同的:计划在 10 秒后完成的任务始终在 10 秒后完成,计划在 20 秒后完成的任务始终在 20 秒后完成。总是。这两项任务都不需要 30 秒才能完成,因为您已同时启动这两项任务。
为了证明这是真的,让我们在测试代码中删除
await
:
function handlePromise() {
p1.then((val) => {
console.log("Namaste JavaScript");
console.log(val);
}).catch((error) => {
console.error("Error:", error);
})
p2.then((val2) => {
console.log("Namaste JavaScript 2");
console.log(val2);
}).catch((error) => {
console.error("Error:", error);
})
}
handlePromise();
您将在场景 1 中看到 p2 首先完成,然后 p1 在 10 秒后完成,而在场景 2 中则发生相反的情况。两个计时器并行运行。
在您的代码中,您基本上是这样做的:
function handlePromise() {
p1.then((val) => {
console.log("Namaste JavaScript");
console.log(val);
return p2;
}).then((val2) => {
console.log("Namaste JavaScript 2");
console.log(val2);
}).catch((error) => {
console.error("Error:", error);
})
}
handlePromise();
因此,在场景 1 中,p2 在 p1 之前完成,但在 p1 完成之前我们不会处理 p2 的结果。因此,当 p1 完成时,p2 的结果也会立即处理,因为它是 10 秒前完成的。
要获得我认为您期望的结果,请不要在想要启动之前启动
setTimeout
:
function startP1 () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise Resolved Value!!");
}, 20000);
});
}
function startP2 () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise Resolved Value!!");
}, 10000);
});
}
async function handlePromise() {
try {
console.log("Hello World!!");
const val = await startP1();
console.log("Namaste JavaScript");
console.log(val);
const val2 = await startP2();
console.log("Namaste JavaScript 2");
console.log(val2);
} catch (error) {
console.error("Error:", error);
}
}
handlePromise();
另外要记住的是,Promise 构造函数的回调是同步执行的,而不是异步的。我们可以通过运行以下代码看到情况是这样的:
console.log('hello');
new Promise((ok,fail) => {
console.log('cruel');
});
console.log('world');
上面的代码打印:
hello
cruel
world
不是
hello, world, cruel
。您传递给 Promise 构造函数的函数是同步执行的。