-1

here is my code

let thoughts = ['1', '2', '3', '4', '5']
i = 0;
const alretMaker = async () => {
    let interval = setInterval(function () {
        const div = document.createElement('div')
        const alret = document.createElement('span')
        document.body.append(div)
        div.append(alret)
        div.className = 'alert primary'
        alret.className = 'close'
        alret.innerText = '×'
        div.append(thoughts[i])
        i++;
        if (i >= thoughts.length) {
            clearInterval(interval)
        }
    }, 1000)
}
const spanMaker = async () => {
    const spans = document.querySelectorAll('span')
    for (let span of spans) {
        span.addEventListener('click', () => {
            span.parentElement.style.display = 'none'
        })
    }
}
const runCode = async () => {
    await alretMaker()
    await spanMaker()
}
runCode()

so in this code, the spanMaker isn't being run when i run my runCode functions, why? my point is for runCode functions, is to first finish the alretMaker functions (which makes all the alrets) then run the spanMaker (which assign display = none when clicked) but that doesn't seems to happen, when i do run spanMaker() after the alret is done, it does work

so how do accomplish that? thank you in advance

Justinas
  • 41,402
  • 5
  • 66
  • 96

2 Answers2

2

Building off of the answer Justina's comment referenced:

async function waitUntil(condition) {
    return await new Promise(resolve => {
        const interval = setInterval(function () {
            const div = document.createElement('div')
            const alret = document.createElement('span')
            document.body.append(div)
            div.append(alret)
            div.className = 'alert primary'
            alret.className = 'close'
            alret.innerText = '×'
            div.append(thoughts[i])
            i++;
            if (i >= thoughts.length) {
                resolve()
                clearInterval(interval)
            }
        }, 1000);
    });
}

setInterval just returns an integer so there's nothing to await. But a promise can be awaited.

Btw, consider renaming 'alret' to 'alert'.

Oskar Grosser
  • 2,804
  • 1
  • 7
  • 18
Dennis Hackethal
  • 13,662
  • 12
  • 66
  • 115
2

Here is an alternative version to accomplish your task:

const thoughts=["one","two","three","four","five"];

function makeAlert(){
  document.body.insertAdjacentHTML("beforeend",
    `<div>${thoughts.shift()} <span>x</span></div>` );
  if (thoughts.length) setTimeout(makeAlert,500);
}
document.body.addEventListener("click",ev=>{
 if (ev.target.tagName=="SPAN" && ev.target.textContent=="x") ev.target.closest("div").style.display="none"
});

makeAlert()
div span {cursor:pointer}

There is no need to venture into "async", "await" or "Promise"-land. Everything can be done by simply chaining a few function calls with a setTimeout() function.

Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43