首页 > 解决方案 > The fetch api in addEventListener only works once

问题描述

The fetch api in addEventListener(click) only works once.

HTML code:

<form action="/register/callback" method="post">
    <input type="text" name="id" placeholder="id" value="${flash.id}" class="infoTp reg confIn" required />
    <div id="useridConf">
        <button type="button" class="infoSub conf" id="cfuserid">Id Confirm</button>
    </div>
    <input type="text" name="email" placeholder="email" value="${flash.email}" class="infoTp reg confIn" required />
    <div id="emailConf">
        <button type="button" class="infoSub conf" id="cfemail">Email Confirm</button>
    </div>
    <input type="password" name="pw" placeholder="password" value="${flash.pw}" class="infoTp reg" required />
    <input type="password" name="pw2" placeholder="second password" value="${flash.pw2}" class="infoTp reg" required />
    <input type="text" name="nickname" placeholder="nickname" value="${flash.nickname}" class="infoTp reg confIn" required />
    <div id="nicknameConf">
        <button type="button" class="infoSub conf" id="cfnickname">Nickname Confirm</button>
    </div>
    <div id="borderReg" class="reg">
        <input type="submit" name="signup_submit" value="Register" class="infoSub" id="regBtn" />
    </div>
</form>

JavaScript code:

let confs = document.getElementsByClassName('conf');
let confIns = document.getElementsByClassName('confIn');
if (confs) {
    for(let i = 0; i < confs.length; i++) {
        confs[i].addEventListener('click', function() {
            if (confIns[i].value) {
                fetch(`/confirm?${confs[i].id.slice(2)}=${confIns[i].value}`).then(function(response){
                    response.text().then(function(text){
                        if (document.getElementById(`${confs[i].id.slice(2)}Span`)) {
                            document.getElementById(`${confs[i].id.slice(2)}Span`).parentNode.removeChild(document.getElementById(`${confs[i].id.slice(2)}Span`));
                        }
                        document.getElementById(`${confs[i].id.slice(2)}Conf`).innerHTML += text;
                        console.log('fin');
                    });
                });
            }
            console.log("hello");
        });
    }
}

After the fetch code is done, the eventlistener doesn't work. How can I fetch multiple times?

标签: javascripthtmladdeventlistenerfetch-api

解决方案


Fetch is asynchronous, so it might be still running while the for loop is also running. You can turn the for loop into a while function.

i = 99999999999999999999...
if(confs){
    i = 0
    while (i<confs.length){ 
       blah...
          fetch(...).then(()=>{blah...i+=1})
       ...blah
    }
}

i = 99999999999999999999...

Then use a fetch().then(()=>{i+=1}). This makes the function wait for the fetch to finish before moving on to the next value. It might fix your problem.

However, this can lead to more problems and might make it more difficult to debug. So I would recommend looking for a way to make the function more synchronous. If you do find a way, please don't forget to edit the post to help other people looking for a solution. :)


推荐阅读