Difficulty wrapping a javascript behavior and holding it for later

javascript, promise, q

Solution

You could use a closure.

queue(function(deferred) {
    return function() {
        // this is the actual function that will be run,
        // but it will have access to the deferred variable
        deferred.resolve();
    };
});

Problem

I am getting into programming with javascript and using `Promises`, right now using `Q.js`. I have finally gotten to a point where I understand what I am doing, but am having a difficult time with a specific behavior. I have one situation where I have reasonably similar code repeated several times. It basically goes like this ... ``` { // start var deferred = Q.defer(); // do something { deferred.resolve(); } return deferred.promise; } ``` Okay, that's all fine and good, but repeating all of this every time was getting annoying, so I attempted to wrap it up in something. This is just an example, it is not the entire javascript file, since most of the other parts are not relevant. ``` { var list = []; queue = function(f) { var deferred = Q.defer(); list.push(f(deferred)); return deferred.promise; } { queue(function(deferred){ // do some work // we want the deferred here so we can resolve it at the correct time deferred.resolve(); }); } } ``` The problem is that I don't want this to run the instant I queue it up. I basically want to build the list, and then run it later. I am running the list using the `reduce` function in `Q.js` ``` { return list.reduce(function(i, f) { return i.then(f); }, Q()); } ``` But this is kind of counter to my goal, since I really don't intend to run them at the same time they are queued. Is there a way to save the execution for later and still pass the deferred object through the function? Update I was asked what I expect the code to do, which is a fair question. I'll try to explain. The purpose of this is to split up the logic because I am using `ASP.NET MVC`, and so I have `_Layout` pages, and then normal views - so there is logic that cannot run until other things are completed, but some times that is on a per-page basis. This method was contrived to deal with that. Essentially it works like this ... Loader.js This is, for lack of a better term or current implementation, a global object. I have plans to change that eventually, but one step at a time. ``` { var Loader = {}; var list = []; initialize = function() { Q().then(step1).then(step2).then(process).then(finalStep); }; queue = function(f) { // push the given function to the list }; process = function() { return list.reduce(function(i,f){ return i.then(f); }, Q()); }; step1 = function() { // generic example // create a promise return deferred.promise; }; // other steps are similar to this. return Loader; } ``` _Layout ``` <head> @RenderSection("scripts", false) <script type="text/javascript"> // we have the loader object already Loader.initialize(); </script> </head> ``` Index ``` @section Scripts { <script type="text/javascript"> Loader.promise(function(deferred){ // do something here. deferred.resolve(); })); </script> } ```

Original source

Related problems