From af8ecd0bac4efb80493af1f679e2463ffe23637c Mon Sep 17 00:00:00 2001 From: Justin Meyer Date: Tue, 30 Oct 2018 21:09:08 -0500 Subject: [PATCH] adds lastTask, runAsTask --- can-queues-test.js | 64 +++++++++++++++++++++++++++++++++++++++- can-queues.js | 33 ++++++++++++++++++--- doc/methods/lastTask.md | 19 ++++++++++++ doc/methods/logStack.md | 2 +- doc/methods/runAsTask.md | 27 +++++++++++++++++ 5 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 doc/methods/lastTask.md create mode 100644 doc/methods/runAsTask.md diff --git a/can-queues-test.js b/can-queues-test.js index 27db649..ed3589a 100644 --- a/can-queues-test.js +++ b/can-queues-test.js @@ -203,7 +203,7 @@ if ( System.env.indexOf( 'production' ) < 0 ) { fullName.queueUpdate(); } setFnName(derivedChild_queueUpdate, 'derivedChild_queueUpdate'); - + map = { name: "map", @@ -420,3 +420,65 @@ QUnit.test("dequeue a priority queue", 0, function(){ queue.flush(); }); + +QUnit.test(".lastTask()", function(){ + function notify () { + var lastTask = queues.lastTask(); + QUnit.equal(lastTask.fn,notify); + } + queues.enqueueByQueue({ + "notify": [notify], + }); + +}); + +QUnit.test(".stack(lastTask)", function(){ + var lastTask; + var outerNotify, innerNotify; + + queues.enqueueByQueue({ + "notify": [outerNotify = function notify () { + + queues.enqueueByQueue({ + "notify": [innerNotify = function notify () { + lastTask = queues.lastTask(); + }], + "domUI": [function domUI () { + var stack = queues.stack(lastTask); + QUnit.equal(stack[0].fn, outerNotify); + QUnit.equal(stack[1].fn, innerNotify); + }] + }); + + }] + }); +}); + + +QUnit.test(".runAsTask(fn)", function(){ + var lastTask; + var outerNotify, innerNotify; + var obj = {}; + var thing = function(){ + queues.enqueueByQueue({ + "notify": [innerNotify = function notify () { + lastTask = queues.lastTask(); + }], + "domUI": [function domUI () { + var stack = queues.stack(lastTask); + QUnit.equal(stack[0].fn, outerNotify); + QUnit.equal(stack[1].fn, thing); + QUnit.deepEqual(stack[1].args[0], 1); + QUnit.equal(stack[1].context, obj); + QUnit.equal(stack[2].fn, innerNotify); + }] + }); + }; + var thingQueued = queues.runAsTask(thing); + + queues.enqueueByQueue({ + "notify": [outerNotify = function notify () { + thingQueued.call(obj, 1); + }] + }); +}); diff --git a/can-queues.js b/can-queues.js index c89dd3e..ce14312 100644 --- a/can-queues.js +++ b/can-queues.js @@ -104,6 +104,28 @@ var queues = { return batchData; } }, + runAsTask: function(fn, reasonLog){ + //!steal-remove-start + if(process.env.NODE_ENV !== 'production') { + return function(){ + queueState.lastTask = { + fn: fn, + context: this, + args: arguments, + meta: { + reasonLog: typeof reasonLog === "function" ? reasonLog.apply(this, arguments): reasonLog, + parentTask: queueState.lastTask, + stack: {name: "RUN_AS"} + } + }; + var ret = fn.apply(this, arguments); + queueState.lastTask = queueState.lastTask && queueState.lastTask.meta.parentTask; + return ret; + }; + } + //!steal-remove-end + return fn; + }, enqueueByQueue: function enqueueByQueue ( fnByQueue, context, args, makeMeta, reasonLog ) { if ( fnByQueue ) { queues.batch.start(); @@ -124,10 +146,13 @@ var queues = { queues.batch.stop(); } }, + lastTask: function(){ + return queueState.lastTask; + }, // Currently an internal method that provides the task stack. // Returns an array with the first task as the first item. - stack: function () { - var current = queueState.lastTask; + stack: function (task) { + var current = task || queueState.lastTask; var stack = []; while ( current ) { stack.unshift( current ); @@ -137,8 +162,8 @@ var queues = { } return stack; }, - logStack: function () { - var stack = this.stack(); + logStack: function (task) { + var stack = this.stack(task); stack.forEach( function ( task, i ) { var meta = task.meta; if( i === 0 && meta && meta.reasonLog) { diff --git a/doc/methods/lastTask.md b/doc/methods/lastTask.md new file mode 100644 index 0000000..1b89bed --- /dev/null +++ b/doc/methods/lastTask.md @@ -0,0 +1,19 @@ +@function can-queues.lastTask lastTask +@parent can-queues/methods + +@description Return last task to be flushed. + +@signature `queues.lastTask()` + + ```js + import {queues} from "can"; + + queues.lastTask() //-> {fn, args, context, meta} + ``` + + @return {Object} Returns a task object that contains: + + - `fn` - The function run + - `args` - The arguments passed to the function + - `context` - The context (`this`) the function was called on + - `meta` - Additional information about the task diff --git a/doc/methods/logStack.md b/doc/methods/logStack.md index 4b17c14..797a134 100644 --- a/doc/methods/logStack.md +++ b/doc/methods/logStack.md @@ -4,7 +4,7 @@ @description Log the tasks that were run that resulted in the current line of code being executed. -@signature `queues.logStack( [type] )` +@signature `queues.logStack()` `logStack()` is a very useful debugging tool for discovering why a particular piece of code was executed by CanJS. It logs to the developer console the tasks that resulted in the current line of diff --git a/doc/methods/runAsTask.md b/doc/methods/runAsTask.md new file mode 100644 index 0000000..ba4fc61 --- /dev/null +++ b/doc/methods/runAsTask.md @@ -0,0 +1,27 @@ +@function can-queues.runAsTask runAsTask +@parent can-queues/methods + +@description Return a function that when called, adds a task that can be logged by [can-queues.logStack]. + +@signature `queues.runAsTask( fn [, makeReasonLog] )` + + This is useful for debugging. + + ```js + import {queues} from "can"; + + var task = queues.runAsTask(function myTask(){ + queues.logStack() + }, function(){ + return ["myTask called on", this, "with",arguments]; + }); + + task(); + ``` + + In production, `runAsTask` simply returns the `fn` argument. + + @param {function} fn A function that will be called by the returned function. + @param {function} [makeReasonLog] A function that will be called with the same `this` and arguments that the returned + function was called with. + @return {function} A function that calls `fn`.