Risposte:
Puoi usare setTimeout
per ottenere un effetto simile:
var a = 1 + 3;
var b;
setTimeout(function() {
b = a + 4;
}, (3 * 1000));
Questo in realtà non "sospende" JavaScript: esegue solo la funzione passata setTimeout
dopo una certa durata (specificata in millisecondi). Sebbene sia possibile scrivere una funzione di sospensione per JavaScript, è consigliabile utilizzarla setTimeout
se possibile in quanto non congela tutto durante il periodo di sospensione.
Nel caso in cui tu abbia davvero bisogno di un sleep()
solo per testare qualcosa. Ma tieni presente che si bloccherà il browser la maggior parte delle volte mentre debuggin - probabilmente è per questo che ti serve comunque. In modalità produzione commenterò questa funzione.
function pauseBrowser(millis) {
var date = Date.now();
var curDate = null;
do {
curDate = Date.now();
} while (curDate-date < millis);
}
Non utilizzare new Date()
in loop, a meno che non si desideri sprecare memoria, potenza di elaborazione, batteria e possibilmente la durata del dispositivo.
Versione ECMAScript 6, utilizzando generatori con rendimento per "blocco del codice":
Poiché la domanda originale è stata pubblicata sette anni fa, non mi sono preoccupato di rispondere con il codice esatto, perché è semplicemente troppo facile e già risposto. Questo dovrebbe aiutare in problemi più complicati, come se hai bisogno di almeno due dormienti o se stai pianificando una sequenza di esecuzione asincrona. Sentiti libero di modificarlo per adattarlo alle tue esigenze.
let sleeptime = 100
function* clock()
{
let i = 0
while( i <= 10000 )
{
i++
console.log(i); // actually, just do stuff you wanna do.
setTimeout(
()=>
{
clk.next()
}
, sleeptime
)
yield
}
}
let clk = clock()
clk.next()
Puoi anche concatenare eventi tramite Promises :
function sleep(ms)
{
return(
new Promise(function(resolve, reject)
{
setTimeout(function() { resolve(); }, ms);
})
);
}
sleep(1000).then(function()
{
console.log('1')
sleep(1000).then(function()
{
console.log('2')
})
})
O sarebbe molto più semplice e meno sofisticato
function sleep(ms, f)
{
return(
setTimeout(f, ms)
)
}
sleep(500, function()
{
console.log('1')
sleep(500, function()
{
console.log('2')
})
})
console.log('Event chain launched')
Se stai solo aspettando che si verifichino delle condizioni, puoi aspettare così
function waitTill(condition, thenDo)
{
if (eval(condition))
{
thenDo()
return
}
setTimeout(
() =>
{
waitTill(condition, thenDo)
}
,
1
)
}
x=0
waitTill(
'x>2 || x==1'
,
() =>
{
console.log("Conditions met!")
}
)
// Simulating the change
setTimeout(
() =>
{
x = 1
}
,
1000
)
Gli ultimi Safari, Firefox e Node.js ora supportano anche async / waitit / promesse.
(A partire dal 1/2017, supportato su Chrome, ma non su Safari, Internet Explorer, Firefox, Node.js)
'use strict';
function sleep(ms) {
return new Promise(res => setTimeout(res, ms));
}
let myAsyncFunc = async function() {
console.log('Sleeping');
await sleep(3000);
console.log('Done');
}
myAsyncFunc();
JavaScript si è evoluto da quando questa domanda è stata posta e ora ha funzioni di generatore e il nuovo asincrono / attende / Promessa è in fase di implementazione. Di seguito ci sono due soluzioni, una con la funzione generatore che funzionerà su tutti i browser moderni e un'altra, usando il nuovo asincrono / wait che non è ancora supportato ovunque.
'use strict';
let myAsync = (g) => (...args) => {
let f, res = () => f.next(),
sleep = (ms) => setTimeout(res, ms);
f = g.apply({sleep}, args); f.next();
};
let myAsyncFunc = myAsync(function*() {
let {sleep} = this;
console.log("Sleeping");
yield sleep(3000);
console.log("Done");
});
myAsyncFunc();
Prestare attenzione al fatto che entrambe queste soluzioni sono di natura asincrona. Ciò significa che myAsyncFunc (in entrambi i casi) tornerà durante il sonno.
È importante notare che questa domanda è diversa da Qual è la versione JavaScript di sleep ()? dove il richiedente richiede il vero sonno (nessun'altra esecuzione di codice sul processo) piuttosto che un ritardo tra le azioni.
let co = gen => (...args) => { let iter = gen(...args); let resume = () => new Promise((resolve, reject) => { let result = iter.next(); if (result.done) resolve(result.value); else Promise.resolve(result.value).then(resume).then(resolve, reject); }); return resume(); };
ti lascerebbe fare let asyncAdd = co(function* (a, b) { console.log('Sleeping'); yield sleep(3000); console.log('Done'); return a + b; }); asyncAdd(3, 4).then(console.log);
usando la definizione di sleep()
dal tuo secondo blocco di codice.
Se vuoi funzioni meno ingombranti di setTimeout
e setInterval
, puoi avvolgerle in funzioni che invertono semplicemente l'ordine degli argomenti e danno loro dei bei nomi:
function after(ms, fn){ setTimeout(fn, ms); }
function every(ms, fn){ setInterval(fn, ms); }
Versioni di CoffeeScript:
after = (ms, fn)-> setTimeout fn, ms
every = (ms, fn)-> setInterval fn, ms
Puoi quindi usarli bene con funzioni anonime:
after(1000, function(){
console.log("it's been a second");
after(1000, function(){
console.log("it's been another second");
});
});
Ora si legge facilmente come "dopo N millisecondi, ..." (o "ogni N millisecondi, ...")
Un altro modo per farlo è usare Promise e setTimeout (nota che devi essere all'interno di una funzione e impostarlo come asincrono con la parola chiave asincrona):
async yourAsynchronousFunction () {
var a = 1+3;
await new Promise( (resolve) => {
setTimeout( () => { resolve(); }, 3000);
}
var b = a + 4;
}
Ecco un modo molto semplice per farlo che "sembra" un sonno / pausa sincrono, ma è un codice asincrono js legittimo.
// Create a simple pause function
const pause = (timeoutMsec) => new Promise(resolve => setTimeout(resolve,timeoutMsec))
async function main () {
console.log('starting');
// Call with await to pause. Note that the main function is declared asyc
await pause(3*1000)
console.log('done');
}
Puoi usare javascript semplice, questo chiamerà la tua funzione / metodo dopo 5 secondi:
setTimeout(()=> { your_function(); }, 5000);
Esistono diversi modi per risolvere questo problema. Se utilizziamo la setTimeout
funzione, scopriamola prima.
Questa funzione ha tre parametri: function
o code
, delay
(in millisecondi) e il parameters
. Poiché è richiesta la funzione o il parametro del codice , gli altri sono opzionali. Dopo aver inserito il ritardo , verrà impostato su zero.
Per maggiori dettagli su setTimeout()
vai a questo link .
Versione semplificata:
var a = 1 + 3;
var b;
console.log('a = ' + a);
setTimeout(function(){
b = a + 4;
console.log('b = ' + b);
}, 1000);
output:
a = 4
24 -> Identificatore numero dell'elenco di timeout attivi
b = 8
Utilizzando il parametro pass:
var a = 1 + 3;
var b;
console.log('a = ' + a);
setTimeout(myFunction, 1000, a);
function myFunction(a)
{
var b = a + 4;
console.log('b = ' + b);
}
output:
a = 4
25 -> Identificatore numerico dell'elenco dei timeout attivi
b = 8
Supporto browser:
Chrome Firefox Edge Safari Opera 1.0 1.0 4.0 1.0 4.0
Questo è il mio modello che mostra come "dormire" o "DoEvents" in javascript usando una funzione di generatore (ES6). Codice commentato:
<html>
<head>
<script>
"use strict"; // always
// Based on post by www-0av-Com /programming/3143928
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
var divelt, time0, globaln = 0; // global variables
var MainGenObj = Main(); // generator object = generator function()
window.onload = function() {
divelt = document.getElementsByTagName("body")[0]; // for addline()
addline("typeof Main: " + typeof Main);
addline("typeof MainDriver: " + typeof MainDriver);
addline("typeof MainGenObj: " + typeof MainGenObj);
time0 = new Date().valueOf(); // starting time ms
MainDriver(); // do all parts of Main()
}
function* Main() { // this is "Main" -- generator function -- code goes here
// could be loops, or inline, like this:
addline("Part A, time: " + time() + ", " + ++globaln); // part A
yield 2000; // yield for 2000 ms (like sleep)
addline("Part B, time: " + time() + ", " + ++globaln); // part B
yield 3000; // yield for 3000 ms (or like DoEvents)
addline("Part Z, time: " + time() + ", " + ++globaln); // part Z (last part)
addline("End, time: " + time());
}
function MainDriver() { // this does all parts, with delays
var obj = MainGenObj.next(); // executes the next (or first) part of Main()
if (obj.done == false) { // if "yield"ed, this will be false
setTimeout(MainDriver, obj.value); // repeat after delay
}
}
function time() { // seconds from time0 to 3 decimal places
var ret = ((new Date().valueOf() - time0)/1000).toString();
if (ret.indexOf(".") == -1) ret += ".000";
while (ret.indexOf(".") >= ret.length-3) ret += "0";
return ret;
}
function addline(what) { // output
divelt.innerHTML += "<br />\n" + what;
}
</script>
</head>
<body>
<button onclick="alert('I\'m alive!');"> Hit me to see if I'm alive </button>
</body>
</html>
Prova questa funzione:
const delay = (ms, cb) => setTimeout(cb, ms)
Ecco come lo usi:
console.log("Waiting for 5 seconds.")
delay(5000, function() {
console.log("Finished waiting for 5 seconds.")
})
O prometti stile:
const delay = ms => new Promise(resolve => {
setTimeout(resolve, ms)
})
Ecco una demo .