javascript promise链没有等待先前的承诺执行 [英] javascript promise chains not waiting for previous promise to execute
问题描述
我很难理解javascript的承诺。我有一个简单的列表,我希望通过添加一个活动类依次突出显示每个元素,每个元素之间有一个暂停。
I'm struggling to understand javascript promises. I have a simple list and I want to highlight each element in turn by adding an "active" class, with a pause between each.
所以我有以下标记 -
So I have the following mark up -
<h2 class="step step1">Promise</h2>
<h2 class="step step2">Promise</h2>
<h2 class="step step3">Promise</h2>
<h2 class="step step4">Promise</h2>
和2个javascript承诺。首先设置步骤 -
and 2 javascript promises. First to set the step -
function setStep(step) {
return new Promise(function (resolve, reject) {
console.log("Step ", step, new Date())
document.querySelectorAll('.step').forEach(function (match) {
match.classList.remove("active");
});
document.querySelector(".step" + step).classList.add("active");
resolve(step);
})
}
以及实施等待的第二个 -
and a second that implements a wait -
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
然后我试图将它们全部链接在一起 -
and then I'm trying to chain it all together like this -
wait(1000)
.then(function () { setStep(1) })
.then(wait(1000))
.then(function () { setStep(2) })
.then(wait(1000))
.then(function () { setStep(3) })
第一次等待似乎按预期执行,但其他一切似乎一起发生,第3步突出显示,没有等待之间。控制台消息都显示相同的时间戳。
The first wait seem to execute as expected but then everything else appears to happen together and step 3 is highlighted, with no waits in between. The console messages all show the same timestamp.
我可以忽略什么?
完整代码如下 -
<style>
.active {
background-color: #C00;
color: #FFF;
}
</style>
<h2 class="step step1">Step 1</h2>
<h2 class="step step2">Step 2</h2>
<h2 class="step step3">Step 3</h2>
<script>
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
function setStep(step) {
return new Promise(function (resolve, reject) {
console.log("Step ", step, new Date())
document.querySelectorAll('.step').forEach(function (match) {
match.classList.remove("active");
});
document.querySelector(".step" + step).classList.add("active");
resolve(step);
})
}
wait(1000)
.then(function () { setStep(1) })
.then(wait(1000))
.then(function () { setStep(2) })
.then(wait(1000))
.then(function () { setStep(3) })
</script>
推荐答案
您需要将函数引用传递给 .then()
,而非承诺。所以改变这个:
You need to pass a function reference to .then()
, not a promise. So change this:
.then(wait(1000))
到此:
.then(wait.bind(null, 1000))
或者:
.then(() => wait(1000))
.then()
只有在向它传递一个稍后可以调用的函数引用时才能正常工作。当你执行 .then(wait(1000))
时,你正在立即执行 wait(1000)
并通过返回值(承诺)到 .then()
。这不是 .then()
的工作方式,你不想立即执行 wait(1000)
。
.then()
only works properly when you pass it a function reference that it can call later. When you do .then(wait(1000))
, you're executing wait(1000)
immediately and passing the return value (a promise) to .then()
. That is not how .then()
works and you didn't want to be executing wait(1000)
immediately either.
或者,您可以创建一个新的 waitFn()
返回一个可以按照你的方式使用的函数(因为它在调用时返回一个函数):
Or, you could make a new waitFn()
that returns a function that could be used in the way you were doing (because it returns a function when called):
function waitFn(t) {
return function() { return wait(t);}
}
然后,你可以这样做:
wait(1000)
.then(function () { setStep(1) })
.then(waitFn(1000))
.then(function () { setStep(2) })
.then(waitFn(1000))
. then(function () { setStep(3) })
这篇关于javascript promise链没有等待先前的承诺执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!