2016-08-09 136 views
0

Während viele Fragen und Antworten mir sagen, warum und was die setTimeout(0) ist, kann ich keine sehr gute Alternative dafür finden.Kann ich setTimeout (Fn, 0) vertrauen, oder sollte ich eine Alternative verwenden?

Mein Problem

Ich habe einen Click-Handler, führt Wich eine Funktion, die eine andere Klasse signalisiert ihren Status zu aktualisieren.

Dieser Click-Handler befindet sich auf dem übergeordneten Element.

Ich habe ein Kontrollkästchen in diesem Element, das aktiviert oder deaktiviert wird.

Da sich der Click-Handler auf dem übergeordneten Element befindet, wird dieser zuerst aufgerufen. Aber ich brauche meine Checkbox, um den Status zu ändern, bevor das Signal gesendet wird.

So verwende ich setTimeout(0), um zu verhindern, dass das Signal gesendet wird, bevor das Kontrollkästchen aktiviert wird.

HTML

<div click.delegate="update()"> 
    <div class="checkbox"> 
     <label> 
      <input checked.bind="group.validated" type="checkbox"> Visibility 
     </label> 
    </div> 
</div> 

Javascript

update(){ 
    setTimeout(()=>{ 
     this.signaler.signal('refresh-groups'); 
    }, 0); 
    return true; 
} 

Im Grunde, was ist passiert, dass die return true; vor der this.signaler.signal Funktion ausgeführt wird. Auf diese Weise wird das Kontrollkästchen überprüft vor das Signal gesendet wird. Beachten Sie, dass dies nicht in regulären onclick Methoden geschieht, bei denen der Checkbox-Status zuerst aktualisiert wird, aber dies ist die Art und Weise, wie sich das Aurelia Framework verhält.

Ich mag nicht das Gefühl, das ich hier erstelle. Ein Timeout von 0 Sekunden bedeutet, dass die Funktion am Ende des Callstacks ist, nicht mehr. Wenn irgendetwas mit meiner return true;-Anweisung passieren würde, was dazu führt, dass sie 0,1 Sekunden wartet, sehe ich das gleiche Problem.

Gibt es eine Alternative, die vertrauenswürdiger ist? Einfach mit einem Promise scheint hier nicht den Trick zu tun.

+0

Für diejenigen, die möglicherweise nicht über 'SetTimeout bekannt (fn, 0)' (mich eingeschlossen), siehe [Link] (http://stackoverflow.com/questions/779379/why-is -settimeoutfn-0-manchmal-nützlich) –

+0

https://developer.mozilla.org/en/docs/Web/API/Window/setImmediate – MysterX

+0

* "Ein Timeout von 0 Sekunden bedeutet, dass die Funktion am Ende des Callstacks ist Nichts mehr. Wenn irgendetwas mit meiner Rückkehr wahr wäre, die Aussage, dass sie 0,1 Sekunden warten würde, stehe ich vor dem gleichen Problem. "* Was meinst du," du hast das gleiche Problem "?Ihr 'setTimeout' Callback ** wird nicht ** ausgeführt, bevor Ihre' update' Methode zurückkehrt, egal wie lange das dauert. –

Antwort

1

ich glaube, das Hauptproblem ist, dass Sie verwenden das click Ereignis, das vor das Eingangselement der Wertänderung ausgelöst. Verwenden Sie stattdessen das Ereignis .

https://gist.run/?id=863282464762b54c8cf67de541bac4d3

+0

Nizza !!! Lass mich dir eine Frage stellen, Danyow. Würde meine Antwort auch in diesem Fall funktionieren? –

+0

@FabioLuz - Es würde definitiv funktionieren. Ich versuche zu vermeiden, die TaskQueue und den Signaler zu verwenden, wo es möglich ist - es gibt normalerweise eine natürlichere Art, Dinge zu tun. –

+0

yeah, deine Lösung ist viel einfacher (auch wenn jemand es abgelehnt WTF?). Ich habe versucht, der Logik von OP zu folgen, es ist gut zu wissen, dass es funktionieren würde (und es wurde auch gewählt ¯ \ _ (ツ) _/¯). Vielen Dank! –

0

Sie könnten this.signaler.signal() als Task ausführen. Zum Beispiel:

import {BindingSignaler} from 'aurelia-templating-resources'; 
import { TaskQueue } from 'aurelia-task-queue'; 

export class App { 

    static inject() { return [BindingSignaler, TaskQueue]; } 

    constructor(signaler, taskQueue) { 
    this.signaler = signaler; 
    this.taskQueue = taskQueue; 
    } 

    update(){ 
    this.taskQueue.queueTask(() => { 
     this.signaler.signal('refresh-groups'); 
    }); 

    return true; 
    } 
} 

Sehen Sie dieses Beispiel https://gist.run/?id=88500143701dab0b0697b17a211af3a7