javascript promise链没有等待先前的承诺执行 [英] javascript promise chains not waiting for previous promise to execute

查看:91
本文介绍了javascript promise链没有等待先前的承诺执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆