Odpowiedzi:
Możesz użyć, setTimeout
aby osiągnąć podobny efekt:
var a = 1 + 3;
var b;
setTimeout(function() {
b = a + 4;
}, (3 * 1000));
Tak naprawdę nie „usypia” JavaScript - po prostu wykonuje funkcję przekazaną setTimeout
po określonym czasie (określonym w milisekundach). Chociaż możliwe jest napisanie funkcji uśpienia dla JavaScript, najlepiej jest z niej korzystać, setTimeout
jeśli to możliwe, ponieważ nie zamraża ona wszystkiego w okresie snu.
Na wypadek, gdybyś naprawdę sleep()
chciał coś przetestować. Należy jednak pamiętać, że podczas debugowania najczęściej powoduje awarię przeglądarki - prawdopodobnie dlatego i tak jest to potrzebne. W trybie produkcyjnym wykomentuję tę funkcję.
function pauseBrowser(millis) {
var date = Date.now();
var curDate = null;
do {
curDate = Date.now();
} while (curDate-date < millis);
}
Nie używaj new Date()
w pętli, chyba że chcesz marnować pamięć, moc obliczeniową, baterię i ewentualnie żywotność urządzenia.
Wersja ECMAScript 6 wykorzystująca generatory z wydajnością do „blokowania kodu”:
Ponieważ oryginalne pytanie zostało wysłane siedem lat temu, nie zawracałem sobie głowy udzieleniem dokładnego kodu, ponieważ jest po prostu zbyt łatwe i już na nie odpowiedziałem. Powinno to pomóc w bardziej skomplikowanych problemach, na przykład jeśli potrzebujesz co najmniej dwóch uśpień lub jeśli planujesz sekwencyjne wykonywanie asynchroniczne. Możesz go zmodyfikować, aby dopasować go do swoich potrzeb.
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()
Możesz także łączyć wydarzenia za pomocą Obietnic :
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')
})
})
Albo byłby znacznie prostszy i mniej wyszukany sposób
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')
Jeśli tylko czekasz na wystąpienie jakiegoś warunku, możesz poczekać w ten sposób
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
)
Najnowsze przeglądarki Safari, Firefox i Node.js obsługują teraz również async / await / promises.
(Od 1/2017 obsługiwane w przeglądarce Chrome, ale nie w 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 ewoluował od czasu zadania tego pytania i ma teraz funkcje generatora, a nowy async / await / Promise jest wdrażany. Poniżej znajdują się dwa rozwiązania, jedno z funkcją generatora, które będzie działać we wszystkich nowoczesnych przeglądarkach, a drugie, wykorzystujące nowy async / await, który nie jest jeszcze wszędzie obsługiwany.
'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();
Zwróć uwagę, że oba te rozwiązania mają charakter asynchroniczny. Oznacza to, że myAsyncFunc (w obu przypadkach) powróci podczas snu.
Należy zauważyć, że to pytanie jest inne niż Jaka jest wersja funkcji sleep () w języku JavaScript? gdzie żądający prosi o prawdziwy sen (brak wykonania innego kodu w procesie) zamiast opóźnienia między akcjami.
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(); };
pozwoliłoby ci let asyncAdd = co(function* (a, b) { console.log('Sleeping'); yield sleep(3000); console.log('Done'); return a + b; }); asyncAdd(3, 4).then(console.log);
użyć definicji sleep()
z drugiego bloku kodu.
Jeśli potrzebujesz mniej niezgrabnych funkcji niż setTimeout
i setInterval
, możesz opakować je w funkcje, które po prostu odwracają kolejność argumentów i nadają im ładne nazwy:
function after(ms, fn){ setTimeout(fn, ms); }
function every(ms, fn){ setInterval(fn, ms); }
Wersje CoffeeScript:
after = (ms, fn)-> setTimeout fn, ms
every = (ms, fn)-> setInterval fn, ms
Następnie możesz ich ładnie używać z anonimowymi funkcjami:
after(1000, function(){
console.log("it's been a second");
after(1000, function(){
console.log("it's been another second");
});
});
Teraz można go łatwo odczytać jako „po N milisekundach…” (lub „co N milisekundach…”)
Innym sposobem jest użycie Promise i setTimeout (pamiętaj, że musisz być wewnątrz funkcji i ustawić ją jako asynchroniczną ze słowem kluczowym async):
async yourAsynchronousFunction () {
var a = 1+3;
await new Promise( (resolve) => {
setTimeout( () => { resolve(); }, 3000);
}
var b = a + 4;
}
Oto bardzo prosty sposób na zrobienie tego, który `` czuje się '' jak synchroniczny sen / pauza, ale jest legalnym kodem asynchronicznym js.
// 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');
}
Możesz użyć zwykłego javascript, to wywoła twoją funkcję / metodę po 5 sekundach:
setTimeout(()=> { your_function(); }, 5000);
Istnieje kilka sposobów rozwiązania tego problemu. Jeśli korzystamy z setTimeout
funkcji, najpierw ją poznajmy.
Ta funkcja ma trzy parametry: function
lub code
, delay
(w milisekundach) i parameters
. Ponieważ parametr funkcji lub kodu jest wymagany, pozostałe są opcjonalne. Jeśli nie wprowadziłeś opóźnienia , zostanie ono ustawione na zero.
Aby uzyskać więcej informacji na temat setTimeout()
tego łącza .
Wersja uproszczona:
var a = 1 + 3;
var b;
console.log('a = ' + a);
setTimeout(function(){
b = a + 4;
console.log('b = ' + b);
}, 1000);
wyjście:
a = 4
24 -> Identyfikator numeryczny listy aktywnych timeoutów
b = 8
Korzystanie z parametru 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);
}
wyjście:
a = 4
25 -> Identyfikator numeru listy aktywnych timeoutów
b = 8
Obsługa przeglądarek:
Chrome Firefox Edge Safari Opera 1,0 1,0 4,0 1,0 4,0
To jest mój model, który pokazuje, jak "spać" lub "DoEvents" w javascript przy użyciu funkcji generatora (ES6). Skomentowany kod:
<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>
Wypróbuj tę funkcję:
const delay = (ms, cb) => setTimeout(cb, ms)
Oto jak go używasz:
console.log("Waiting for 5 seconds.")
delay(5000, function() {
console.log("Finished waiting for 5 seconds.")
})
Lub obiecaj styl:
const delay = ms => new Promise(resolve => {
setTimeout(resolve, ms)
})
Oto demo .