我可以信任setTimeout(fn,0),还是应该使用替代方案?

时间:2016-08-09 14:43:46

标签: javascript ecmascript-6 aurelia

虽然很多问题和答案都告诉我setTimeout(0)为什么以及为什么,我找不到一个很好的选择。

我的问题

我有一个点击处理程序,它执行一个函数,指示另一个类更新其状态。

该点击处理程序位于父元素上。

我在该元素中有一个复选框,可以选中或取消选中。

因为click处理程序位于父元素上,所以首先调用它。但是我需要我的复选框才能在发送信号之前更改状态。

所以我使用setTimeout(0)来阻止在选中复选框之前发送信号。

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;
}

基本上,正在发生的事情是return true;this.signaler.signal函数之前执行。这样,在发送信号之前,复选框将被检查。 请注意,在首先更新复选框状态的常规onclick方法中不会发生这种情况,但这是Aurelia框架的行为方式。

我不喜欢我在这里创造的感觉。超时为0秒意味着该函数位于callstack的末尾,仅此而已。如果我的return true;声明发生任何事情导致它等待0.1秒,我面临同样的问题。

有没有更值得信赖的选择?简单地使用Promise似乎没有在这里做到这一点。

2 个答案:

答案 0 :(得分:1)

我认为主要问题是您使用{<1}}事件在输入元素的值更改之前触发。请改用click事件。

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

答案 1 :(得分:0)

您可以将this.signaler.signal()作为任务运行。例如:

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;
  }
}

请参阅此示例https://gist.run/?id=88500143701dab0b0697b17a211af3a7