且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

自定义属性附加事件为时过早?

更新时间:2023-10-14 09:06:10

让我消除您对TaskQueue的误解.

Allow me take away your misconception about the TaskQueue.

您及时移动事物导致维护问题的想法肯定适用于使用setTimeout(),因为这会导致实际的延迟,并迫使执行进入下一个事件循环. queueTask()差不多是同一件事(内部使用setTimeout()).

Your idea of moving things in time causing maintenance issues would certainly apply to using setTimeout() because that incurs an actual delay, and forces execution onto the next event loop. queueTask() is more or less the same thing (it uses setTimeout() internally).

但是,TaskQueue的queueMicroTask()方法的工作方式却大不相同.

However, the TaskQueue's queueMicroTask() method works very differently.

当您调用queueMicroTask()时,与queueTask()setTimeout()不同,该任务被安排为在同一事件循环上立即执行.这是一种非常健壮的机制,可以保证执行顺序,通常在进行任何DOM操作之前在attached()中使用它都是一种好习惯.

When you call queueMicroTask(), unlike queueTask() and setTimeout(), the task is scheduled for immediate execution on the same event loop. This is a very robust mechanism with a guaranteed execution order, and it's generally considered good practice to use it within attached() before doing any DOM manipulation.

实际上,Aurelia在不同地方内部使用了queueMicroTask()(主要在bindingtemplating-resources中).两个值得注意的地方是:

In fact, queueMicroTask() is used internally by Aurelia in various places (mostly in binding and templating-resources). Two notable places are:

  • 属性和集合观察者使用它来延迟"通知订阅者,直到所有其他绑定完成其内部更新工作为止
  • repeat属性用于设置ignoreMutations标志(在刷新队列后取消设置),以防止在更新其内部集合时进行无限递归
  • Property- and collection observers use it to "delay" notifying subscribers until all other bindings have completed their internal updating work
  • The repeat attribute uses it to set an ignoreMutations flag (and unset it after the queue is flushed) to prevent infinite recursion while updating its inner collection

您通常可以认为bind()和Attached()挂钩有两个阶段":非排队阶段和排队阶段.排队阶段是组件完成工作时,它首先要依靠其他(通常是递归的)过程来完成整个组件图.

You can generally consider there to be two "phases" to the bind() and attached() hooks: a non-queued, and a queued phase. The queued phase is when components do work that relies on the whole component graph to first be done with some other (usually recursive) process.

queueMicroTask() 不延迟执行,只需将其推入调用堆栈的末尾即可

queueMicroTask() does not delay execution, just pushes it to the end of the call stack

在功能上等同于将函数作为回调传递到调用堆栈的末尾,但省去了编写定位最后一个调用并将其全部连接所需的意大利面条代码的麻烦.超级干净.

It's the functional equivalent of passing the function as a callback to the end of the call stack, but saves you the trouble of writing the spaghetti code required to locate that last call and wire it all up. It's super clean.

其所有li元素都是根据 路由器的导航列表.这是在 attached 事件中发生的 组件

all its li elements are dynamically created based on the items in the router's navigation list. This is happening in the attached event of the component

请参见,每当在attached()期间创建任何内容时,您都不能依赖于在另一个组件attached()期间存在的东西,因为这取决于编译/组成的顺序.这是内部问题.对于自定义属性,尤其是为true.自定义属性(尤其是样式库中的属性)在各处都使用TaskQueue,因为这是它们依赖DOM的唯一方法.

See, whenever you create anything during attached(), you can't rely on that thing being there during another component's attached() as this depends on the order of compilation/composition. That's an internal matter. This is especially true for custom attributes. Custom attributes (particularly those in style libraries) use the TaskQueue all over the place because it's the only way they can rely on the DOM being done.

在这里使用queueMicroTask()将保证两件事:

Using queueMicroTask() here will guarantee two things:

  • 使用附件和渲染的第一遍"完全完成aurelia时执行.
  • 完成aurelia后,将立即立即执行-甚至不会延迟一微秒.
  • It's executed when aurelia is completely done with the "first pass" of attacheds and rendering
  • It's executed immediately when aurelia is done with that - not even a microsecond delayed.

解决这个问题的***方法(也许是唯一正确的方法)的确是使用TaskQueue-我保证:)

The best (and perhaps only correct) way to address this is indeed by using the TaskQueue - I promise :)