can-zone is a library that implements Zones.
can-zone是实现Zones的库。
Zones are an abstraction allowing you to write cleaner code for a variety of purposes, including implementing server-side rendered (SSR) applications, profiling, more useful stack traces for debugging, or a clean way to implement dirty checking.
区域是一种抽象,使您可以出于各种目的编写更清晰的代码,包括实现服务器端呈现(SSR)应用程序,分析,更有用的调试堆栈跟踪或实现脏检查的干净方法。
This article will:
本文将:
Explain what Zones are. 解释什么是区域。 Explain how can-zone works. 解释can-zone如何工作。 Show can-zone's basic API. 显示can-zone的基本API。Zones can be difficult to understand at first, so this article will stick to the basics. Next week I'll publish a follow-up article on blog.bitovi.com explaining how DoneJS uses can-zone to elegantly allow apps to be server-side rendered.
一开始可能很难理解区域,因此本文将坚持基础知识。 下周我将发布在后续文章blog.bitovi.com解释如何DoneJS用途可以区以优雅允许应用是服务器端渲染。
As you already know, JavaScript is an asynchronous language. What this means in practice is that JavaScript engines contain (multiple) queues that they use to keep track of asynchronous tasks to be executed later. To think about this, take a look at a simple example of asynchronous code:
如您所知,JavaScript是一种异步语言。 实际上,这意味着JavaScript引擎包含(多个)队列,它们用于跟踪以后要执行的异步任务。 考虑这一点,请看一个简单的异步代码示例:
Async Example 异步示例This code runs a function, app, that schedules the function logging to be called twice with 2 different arguments. Breaking down what happens in the JavaScript engine:
此代码运行一个函数app ,该函数计划使用2个不同的参数两次调用该函数logging 。 分解JavaScript引擎中发生的情况:
The script task is executed which defines and executes the app function. setTimeout is called twice, scheduling their callbacks to run after 10ms.
执行脚本任务,该脚本任务定义并执行app功能。 setTimeout被调用两次,安排其回调在10毫秒后运行。
After 10ms the first task will be taken from the queue and run to completion, logging 0 to 500.
10毫秒后,第一个任务将从队列中取出并运行至完成,记录0到500。
After the completion of the first task, the second task will be taken from the queue and run to completion. It will log from 0 to 5000.
第一个任务完成后,第二个任务将从队列中取出并运行到完成。 它将记录从0到5000。
The task queue is now empty.
现在,任务队列为空。
For a deeper dive into JavaScript tasks and microtasks check out Jake Archibald's post on the subject.
要更深入地了解JavaScript任务和微任务,请查看Jake Archibald 关于该主题的文章 。
Zones provide a way to hook into the behavior of the JavaScript event loop. To better visualize what happens in the above code, see what happens when the same code is run in a Zone using can-zone.
区域提供了一种挂钩JavaScript事件循环行为的方法。 为了更好地可视化上述代码中发生的情况,请查看使用can-zone在区域中运行相同的代码时发生的情况。
Zone beforeTask and afterTask 之前和之后的区域Here we have the same code but with the addition of logging before and after each task runs. Notice that the first two things that are logged are "beforeTask" and "afterTask". This is because the running of app is, itself, a task. Then when the functions scheduled by the setTimeout are executed "beforeTask" and "afterTask" are logged for each of them as well.
在这里,我们有相同的代码,但是在每个任务运行之前和之后都添加了日志记录。 请注意,记录的前两件事是“ beforeTask”和“ afterTask”。 这是因为app的运行本身就是一项任务。 然后,当执行由setTimeout调度的函数时,也会分别为每个函数记录“ beforeTask”和“ afterTask”。
With this building block we can create more useful abstractions for working with code that runs in an event loop. One that can-zone provides for you is the ability to know when all asynchronous tasks are complete. Each Zone has an associated Promise that will resolve when all tasks queues are emptied.
使用此构建块,我们可以创建更多有用的抽象,以处理在事件循环中运行的代码。 can-zone为您提供的一项功能是知道所有异步任务何时完成。 每个区域都有一个关联的Promise,该承诺将在清空所有任务队列时解决。
In the following example we have an application that performs two AJAX requests to display lists, and at the top the time it took to render. This can be written using Promises by waiting for all of the promises to resolve like below:
在以下示例中,我们有一个应用程序,该应用程序执行两个AJAX请求以显示列表,并在顶部花费了渲染时间。 可以使用Promises来编写此代码,方法是等待所有的Promise如下解决:
Frameworks 构架With only 2 asynchronous tasks to wait on this isn't so bad, but will scale poorly as the code becomes more complex (like if the requests were triggered as a side effect of some other function call). can-zone allows us to write this same code without manually keeping track of each request's promise:
仅需等待2个异步任务就可以了,但是随着代码变得更加复杂(例如,由于其他函数调用的副作用触发了请求),伸缩性将很差。 can-zone允许我们编写相同的代码,而无需手动跟踪每个请求的承诺:
Frameworks II 框架二This tells us how long until the lists are fully displayed, but we can do better, and know how long it took for our code to actually execute, eliminating network latency from the equation. Using the Zone hooks discussed before, beforeTask and afterTask, we can measure just the time in which our JavaScript is executing:
这告诉我们多久,直到列表完全显示出来,但我们可以做的更好,并且知道过了多长时间了我们的代码实际执行,消除了方程网络延迟。 使用之前,beforeTask和afterTask讨论的Zone挂钩,我们可以仅测量执行JavaScript的时间:
Faster Load 加载更快This technique provides insight into why this code takes so long to render; it's not the fault of poorly written code but rather network latency is the problem. With that information we can make more informative optimizations for the page load time.
这项技术可以洞悉为什么这段代码需要花费这么长的时间来渲染。 这不是写得不好的代码的问题,而是网络延迟是问题所在。 有了这些信息,我们就可以对页面加载时间进行更多有益的优化。
The concept of Zones is gaining steam in JavaScript. Angular has a similar Zone library. But while Angular's zone.js is aimed at aiding debugging and improving dirty checking code, can-zone is focused on solving server-side rendering.
在JavaScript中,Zones的概念越来越流行。 Angular具有类似的Zone库。 但是,尽管Angular的zone.js旨在帮助调试和改进脏检查代码,但can-zone却专注于解决服务器端渲染。
In the future Zones might be part of the EMCAScript standard, but for now can-zone implements the behavior by wrapping functions that trigger asynchronous events (including XHR, setTimeout, requestAnimationFrame). can-zone not only wraps the functions, but also keeps count of when tasks complete, and provides a Promise-like API that lets you know when all asynchronous behavior has completed.
将来,区域可能是EMCAScript标准的一部分,但是现在,区域可以通过包装触发异步事件的函数(包括XHR,setTimeout,requestAnimationFrame)来实现行为。 can-zone不仅包装函数,而且还保留任务完成的时间,并提供类似于Promise的API,让您知道所有异步行为何时完成。
Above we saw some simple examples of Zones; below is a more complex example. It illustrates that even when asynchronous calls are nested inside of each other, can-zone will wait for everything to complete.
在上方,我们看到了一些简单的区域示例; 下面是一个更复杂的示例。 它说明,即使异步调用彼此嵌套在一起,can-zone也会等待所有操作完成。
can zone 可以区域Under the hood, can-zone is overwriting the following methods:
在后台,can-zone覆盖了以下方法:
setTimeout setTimeout clearTimeout clearTimeout XMLHttpRequest XMLHttpRequest requestAnimationFrame requestAnimationFrame Promise 诺言 process.nextTick (in Node) process.nextTick(在Node中) MutationObserver 突变观察者It doesn't change their core behavior. It simply increments a counter to keep track of how many callbacks remain. The counter is decremented when those callbacks are called. When the count reaches zero, the Zone's Promise is resolved.
它不会改变他们的核心行为。 它只是增加一个计数器来跟踪剩余的回调数。 调用这些回调时,计数器递减。 当计数达到零时,将解决区域的承诺。
Zone.ignore allow users to ignore (not wait on) certain functions. You might use this if you have code doing recursive setTimeouts (because that will never complete), or for some API call that is not important enough to wait on. Here's an example usage:
Zone.ignore允许用户忽略(而不是等待)某些功能。 如果您有执行递归setTimeouts的代码(因为它将永远不会完成),或者某些不重要的API调用需要等待,则可以使用此方法。 这是一个示例用法:
function recursive(){ setTimeout(function(){ recursive(); }, 20000); } var fn = Zone.ignore(recursive); // This call will not be waited on. fn();Zone.waitFor is a way to define custom asynchronous behavior. You can think of it as being the opposite of Zone.ignore. Let's say there is some asynchronous tasks that can-zone doesn't yet implement, or a Node library with with custom C++ bindings that do asynchronous things without our knowledge. You can still wrap these chunks of code to ensure they are waited on:
Zone.waitFor是定义自定义异步行为的一种方法。 您可以认为它与Zone.ignore相反。 假设有些尚无法实现的异步任务,或者带有自定义C ++绑定的Node库在我们不知情的情况下执行异步操作。 您仍然可以包装这些代码块,以确保等待它们:
var Zone = require("can-zone"); var fs = require("fs"); module.exports = function(filename) { fs.readFile(__dirname + filename, "utf8", Zone.waitFor(function(err, file){ Zone.current.data.file = file; })); };can-zone provides hooks to write code that runs at various points in the Zone lifecycle:
can-zone提供了钩子来编写在Zone生命周期的各个点运行的代码:
created - Called when the Zone is first created. 创建-首次创建区域时调用。 ended – Called when the Zone is about to resolve. 已结束–在区域即将解决时调用。 beforeTask – Called before each asynchronous task runs. beforeTask –在每个异步任务运行之前调用。 afterTask – Called after each asynchronous task runs. afterTask –在每个异步任务运行之后调用。beforeRun - Called immediately before the Zone's run function is executed.
beforeRun-在区域的run功能执行之前立即调用。
These hooks are useful when implementing plugins. Earlier we created a simple performance plugin that used beforeTask and afterTask to time how long each task took to execute.
这些钩子在实现插件时很有用。 之前我们创建了一个简单的性能插件,该插件使用beforeTask和afterTask来计时每个任务执行的时间。
can-zone's constructor function takes a special config object called a ZoneSpec. The ZoneSpec object is where you:
can-zone的构造函数使用一个名为ZoneSpec的特殊配置对象。 ZoneSpec对象是您所在的位置:
Create callbacks for the lifecycle hooks. 为生命周期挂钩创建回调。 Inherit behaviors from other plugins. 从其他插件继承行为。 Define your own hooks that other plugins (that inherit from you) can provide callbacks for. 定义您自己的钩子,其他插件(从您那里继承)可以为其提供回调。 Define globals that should be overwritten in the Zone's async callbacks. 定义应在区域的异步回调中覆盖的全局变量。Here's an example of a plugin that changes the title of your page randomly.
这是一个可随机更改页面标题的插件示例。
var titleZone = { beforeTask: function(){ document.title = Math.random() + " huzzah!"; } }; var zone = new Zone({ plugins: [titleZone] });can-zone comes with a few of plugins you might find useful:
can-zone随附了一些您可能会发现有用的插件:
can-zone/xhr: Can be used on the server and client (assuming you have an XMLHttpRequest shim for Node) to provide caching capabilities when server-side rendering. can-zone / xhr:可以在服务器和客户端上使用(假设您具有Node的XMLHttpRequest填充),以在服务器端呈现时提供缓存功能。 can-zone/timeout: Define a timeout, in milliseconds, at which time the Zone promise will be rejected. can-zone / timeout:定义一个超时(以毫秒为单位),此时将拒绝区域承诺。 can-zone/debug: Used in conjunction with can-zone/timeout, provides stack traces of each async task that failed to complete within the timeout. can-zone / debug:与can-zone / timeout结合使用,提供每个在超时时间内未能完成的异步任务的堆栈跟踪。GitHub project page
GitHub项目页面
jQuery-only can-zone SSR example with jQuery
jQuery的仅jQuery可以区域SSR示例
NPM project page
NPM项目页面
Install it: npm install can-zone
安装它: npm install can-zone
翻译自: https://davidwalsh.name/can-zone
相关资源:SHT 3184-2017 石油化工罐区自动化系统设计规范.pdf