¿Es posible que se mencione a continuación la salida usando setTimout ? En caso afirmativo, comparta su opinión: -
console.log("1st"); setTimeout(()=>{ console.log("2nd"); },0); console.log("3rd");**La salida debe ser **
1st 2nd 3rdLa respuesta de Majed Badawi muestra una forma de lograr lo que desea, pero es solo una construcción que sería similar a simplemente colocar su tercer registro dentro de la devolución de llamada setTimeout después del segundo.
Hay importantes razones conceptuales para ello.
JavaScript es un lenguaje controlado por eventos, donde tiene algo llamado bucle de eventos que verifica nuevos eventos y los procesa sin parar.
Lo que está buscando aquí es una forma de usar setTimeout como lo haría con sleep en PHP, C u otros. Simplemente no existe.
sleep es una instrucción de bloqueo: el programa espera X segundos antes de continuar. Si hace esto en JavaScript, evitará que se ejecute el bucle de eventos y ni siquiera querrá intentar hacer esto. Si realmente insiste, puede verificar si ha transcurrido suficiente tiempo en una declaración de while , esto congelará su navegador en un entorno de front-end o evitará el manejo de nuevas solicitudes en un entorno de back-end.
Más sobre esto aquí https://cloudoki.com/js-dont-block-the-event-loop/
Por el contrario, setTimeout activará un evento para el oyente proporcionado después de un tiempo, el resto del programa (y el bucle de eventos) continuará ejecutándose.
Usando asíncrono/espera:
const foo = () => new Promise(resolve => { setTimeout(() => { console.log("2nd"); resolve(); }, 0); }); (async () => { console.log("1st"); await foo(); console.log("3rd"); })();sleep no existe, pero puedes hacerlo por tu cuenta 💤
function sleep(ms) { return new Promise(r => setTimeout(r, ms)) } async function main() { console.log(1) await sleep(1000) console.log(2) await sleep(1000) console.log(3) await sleep(1000) return "done" } main().then(console.log, console.error) ¿Pensar async..await es demasiado mágico? Probemos con un generador -
function sleep(ms) { return Task(k => setTimeout(k, ms)) } function* main() { console.log(1) yield sleep(1000) console.log(2) yield sleep(1000) console.log(3) yield sleep(1000) return Task(k => k("done")) } function Task(runTask) { return { runTask, bind: f => Task(k => runTask(x => f(x).runTask(k))) } } function coroutine(f) { function then(v) { let {done, value} = f.next(v) return done ? value : value.bind(then) } return then() } coroutine(main()).runTask(console.log)¿Generadores demasiado sofisticados? Probemos una abstracción de bajo nivel:
function sleep(ms, then) { setTimeout(then, ms) } function main(then) { console.log(1) sleep(1000, _ => { console.log(2) sleep(1000, _ => { console.log(3) sleep(1000, _ => { then("done") }) }) }) } main(console.log)