From b9adc76dc7b1c62835225c7e954e44321c733c53 Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Tue, 16 May 2017 14:06:46 -0700 Subject: [PATCH] Clear the stack if onmessage is called before the previous invocation finishes --- spec/core/ClearStackSpec.js | 21 +++++++++++++++++++++ src/core/ClearStack.js | 13 ++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/spec/core/ClearStackSpec.js b/spec/core/ClearStackSpec.js index 26804be4..a43370ad 100644 --- a/spec/core/ClearStackSpec.js +++ b/spec/core/ClearStackSpec.js @@ -37,6 +37,27 @@ describe("ClearStack", function() { expect(called).toBe(true); }); + it("calls setTimeout when onmessage is called recursively", function() { + var fakeChannel = { + port1: {}, + port2: { postMessage: function() { fakeChannel.port1.onmessage(); } } + }, + setTimeout = jasmine.createSpy('setTimeout'), + global = { + MessageChannel: function() { return fakeChannel; }, + setTimeout: setTimeout, + }, + clearStack = jasmineUnderTest.getClearStack(global), + fn = jasmine.createSpy("second clearStack function"); + + clearStack(function() { + clearStack(fn); + }); + + expect(fn).not.toHaveBeenCalled(); + expect(setTimeout).toHaveBeenCalledWith(fn, 0); + }); + it("falls back to setTimeout", function() { var setTimeout = jasmine.createSpy('setTimeout').and.callFake(function(fn) { fn() }), global = { setTimeout: setTimeout }, diff --git a/src/core/ClearStack.js b/src/core/ClearStack.js index 507b398a..5a63a0ac 100644 --- a/src/core/ClearStack.js +++ b/src/core/ClearStack.js @@ -4,11 +4,22 @@ getJasmineRequireObj().clearStack = function(j$) { head = {}, tail = head; + var taskRunning = false; channel.port1.onmessage = function() { head = head.next; var task = head.task; delete head.task; - task(); + + if (taskRunning) { + global.setTimeout(task, 0); + } else { + try { + taskRunning = true; + task(); + } finally { + taskRunning = false; + } + } }; return function clearStack(fn) {