• 异步方法补丁

    异步方法补丁

    这里我们将看看如何通过异步回调传播zone的基本机制。 (注意:实际工作情况有点复杂,因为它们通过稍后讨论的任务调度机制进行调度,为了清楚起见,该示例进行了简化)。

    1. // 保存原始的setTimeout引用
    2. let originalSetTimeout = window.setTimeout;
    3. // Overwrite the API with a function which wraps callback in zone.
    4. window.setTimeout = function(callback, delay) {
    5. // Invoke the original API but wrap the callback in zone.
    6. return originalSetTimeout(
    7. // Wrap the callback method
    8. Zone.current.wrap(callback),
    9. delay
    10. );
    11. }
    12. // Return a wrapped version of the callback which restores zone.
    13. Zone.prototype.wrap[c] = function(callback) {
    14. // Capture the current zone
    15. let capturedZone = this;
    16. // Return a closure which executes the original closure in zone.
    17. return function() {
    18. // Invoke the original callback in the captured zone.
    19. return capturedZone.runGuarded(callback, this, arguments);
    20. };
    21. };

    关键点:

    • Zones 的猴子补丁方法只修补一次。
    • 进入/离开 zone 只需更改Zone.current的值。(不需要进一步的猴子补丁)
    • Zone.prototype.wrap method provides convenience for wrapping callbacks. (The wrapped callback is executed through Zone.prototype.runGuarded())
    • Zone.prototype.runGuarded() is just like Zone.prototype.run(), but with extra try-catch block for handling exceptions described later.
    1. // Save the original reference to Promise.prototype.then.
    2. let originalPromiseThen = Promise.prototype.then;
    3. // Overwrite the API with function which wraps the arguments
    4. // NOTE: this is simplified as actual API has more arguments.
    5. Promise.prototype.then = function(callback) {
    6. // Capture the current zone
    7. let capturedZone = Zone.current;
    8. // Return a closure which executes the original closure in zone.
    9. function wrappedCallback() {
    10. return capturedZone.run(callback, this, arguments);
    11. };
    12. // Invoke the original callback in the captured zone.
    13. return originalPromiseThen.call(this, [wrappedCallback]);
    14. };

    关键点:

    • Promises handle their own exceptions and so they can’t use Zone.prototype.wrap(). (We could have separate API, but Promise is the exception to the rule, and so I did not feel justified creating its own API.)
    • Promise API较多,在此示例中未显式显示。