2011-12-12 3 views
5

So che la differenza al momento sarebbe trascurabile a causa di inaccurati timer del browser, ma per ragioni di conoscenza se non altro: esiste un browser che supporti setInterval e setTimeout, ma richiede che venga passato un valore intero come ritardo?È sicuro passare setInterval o setTimeout a un ritardo frazionario?

Oppure, riformulato con esempi, è questa:

setInterval(animate,50/3); 

come cross-browser compatibile come questo?

setInterval(animate,17); 
+0

Il modo in cui è definito, il secondo argomento è il "numero di millisecondi". Ora, se quel numero dovrebbe essere naturale non è definito ... –

+0

@ ŠimeVidas È perfettamente definito. Vedi le specifiche DOM ;-) –

risposta

6

È perfettamente sicuro.

(Come RobG fa notare, non ho fornire un riferimento alle regole del ponte DOM/JS se stessi e si raccomanda prudenza FWIW, credo -. Ma non hanno alcun riferimento a conclusivamente Stato - che ToIntegerè parte del bridge dell'interfaccia. Ecco un jsfiddle che mostra il timeout passato come una stringa, un float e un integrale (stesso tipo di float in JS) che funziona bene in FF8 e IE9. Risposte gradite.)

è perché the DOM interface only accepts integers per il ritardo in setTimeout/setInterval - sì, questi sono definiti nel DOM, non in ECMAScript. Il valore del ritardo viene convertito in modo appropriato in un valore integrale per primo (e in questo aspetto la funzione [JS-internal] ToInteger viene invocata che esegue un troncamento *).

Tuttavia, i numeri di esempio effettivamente produrrà risultati leggermente diversi (anche se potrebbe non essere notevole) :-)

Questo perché, 50/3 (16.66andsomemore ->16) e 17specificano diversi timeout .

Felice codifica.


* ToInteger è definito come sign(number) * floor(abs(number)), esclusi i casi particolari. Vedere la Sezione 9.4 della 5 ° edizione delle specifiche ECMAScript.

+0

Ok, quindi questa specifica sta descrivendo l'implementazione C (o qualcos'altro non javascript), giusto? Quindi il troncamento si verifica al di fuori dell'ambiente javascript? –

+0

@ skier88 Tecnicamente l'implementazione DOM non * deve * essere in C - sebbene sospetto che sia nella maggior parte dei casi - ma limita il valore a un "long" integrale. C'è una porzione [n inaccessibile all'utente] del motore JS che sa come "parlare al DOM" che fa le conversioni al/dal DOM. Il collegamento pubblicato copre solo i contratti * dell'interfaccia *. La funzione 'ToInteger' è una funzione interna definita in ECMAScript, e credo - ma potrei sbagliarmi - che questo (o un equivalente) sia usato nella conversione integrale. –

+0

Sì, so che la lingua può variare, mi aiuta solo a pensare ad un linguaggio di programmazione di esempio per visualizzare a quale codice di livello viene eseguito.Grazie per la risposta: probabilmente avrei dovuto scaricare la specifica molto tempo fa. –

0

Immagino che il secondo parametro dovrebbe essere valutata come espressione e fintanto che restituisce un numero che funzionerà. Sembra funzionare in cromo. Assicurati solo di non dividere per zero!

0

Queste funzioni prevedono millisecondi. Dubito che potresti aspettarti un'accuratezza superiore a 10 ms e browser enforce timer restrictions.

A Firefox non importa i valori decimali. Tu can test in tutti gli altri browser che ti interessano.

+0

Grazie per la risposta. Come sopra, non mi interessa il tempismo preciso tanto quanto deriva (per quanto impercettibile possa essere). –

3

Javascript non fa alcuna distinzione tra numeri in virgola mobile e numeri interi, e sono lo stesso tipo di dati sotto la cappa. 1 e 1.0 sono bit in bit identici in memoria.

Quindi sì, è possibile passare un valore frazionario senza problemi reali. È un JavaScript perfettamente valido. E anche se richiedesse un numero intero, è più probabile che lo farebbe semplicemente e silenziosamente.

Ma non aspettatevi che sia accurato! Un'ora di 0.1, 1 o anche 4.87 probabilmente si attiverà molto vicino allo stesso tempo a causa della scarsa granularità della pianificazione della richiamata.

+0

Grazie, non pensavo ai tipi di dati per qualche motivo. E buon punto sul granulatiry - IIRC, in realtà è spesso meno di 15ms. La mia preoccupazione è in realtà solo per la deriva (probabilmente impercettibile) di un intervallo di lunga durata. –

+0

La deriva è reale ed è stato un problema che ho incontrato di recente con l'utilizzo di ritmi musicali temporali. E fa schifo. Questa è stata la mia soluzione: http://alexwayne.tumblr.com/post/13744997785/accurateinterval Oppure saltare la prosa e ottenere il mio codice raw qui: https://gist.github.com/1d99b3cd81d610ac7351 –

+0

Il fatto che '1' e '1.0' rappresenta lo stesso valore Numero nella lingua JavaScript non è rilevante qui. La domanda riguarda il comportamento della funzione 'setTimeout'. Nota che questa funzione non fa parte del linguaggio JavaScript. È una funzione browser specificata nello standard HTML. Per quanto ne so, se viene fornito un numero non naturale come secondo argomento (come '1.23'), il comportamento non è definito, il che significa che spetta ai browser implementare un comportamento per questo. –