Ciel
Ciel

Reputation: 4440

Q.js and order of execution confusion within ASP.NET MVC

I have adopted the library Q.js into my program to try and solve some problems with the order of execution in my code, I am new to promises and deferred in general, so this is a pretty difficult step for me.

At this point in time, I am using Q v1 within ASP.NET MVC, and therefore I am using Visual Studio 2013.

Now, the actual code for what I am doing is a great deal longer than this, but I'll attempt to be concise, as I often get told my questions are too long and verbose.

I start by including q.js and require.js normally, nothing special is going on here. It works fine, it compiles, it runs, all is happy and well.

@Scripts.Render("~/scripts/q")
@Scripts.Render("~/scripts/require")

<script type="text/javascript">
   Q().then(function(){
      // some code executes here.
      $.blockUI(); // the whole page is blocked while loading.
      console.log("[1] first step. blocking the page."); 
   }).then(function() {
      console.log("[2.1] starting the second step.");
      require(['home/app/init'], function(app) {
         console.log("[2.2] within the require function.");
         new app.init().wiring(); // this does some preliminary stuff for the app
      });
      console.log("[2.3] outside of the require function.");
   }).then(function() {
      console.log("[3.1] made it to the third step. stuff happens.");
   });
</script>

Now, running this code, the console output for 2.1 and 2.3 are visible before 2.2 - which is the crux of the problem. I want it to run in order. So I dug a bit more, and found this suggestion; changing my require call to look more like this was suggested to me ..

// ....
.then(function(){
   var promise = Q.when(require['home/app/init'], function(app) {
                    console.log("[2.2.1] within the require");
                    new app.init().wiring();
                 }).then(function() {
                    console.log("[2.2.2] I expect to see this after 2.2.1");
                 });
  console.log("[2.3] outside of the require function.");
});

Now I get that 2.3 will still run before 2.2.1, but I'm still seeing 2.2.2 running before 2.2.1 - and I thought that wrapping the behavior in the Q.when(fn) was supposed to fix that?

Can someone help me understand why these are not running in the order I am asking them to?

For a bit more information, the file home/app/init is actually a Typescript file that looks a bit like this;

home/app/init.ts

export class init {
   public function wiring() {
      // some simple things happening here, nothing special.
   }
}

I am not sure if this question qualifies to have the ASP.NET MVC tag, but the fact that I am using that framework is paramount to the tooling I use, which does have influence over what I can do (for instance, I'm having a hard time with things involving node.js because of Visual Studio) - so I am tagging it explicitly to be sure people realize the kind of development environment I am in.

Update

I have made a bit of progress on this, though I am still a bit uncertain. At the moment, the following code seems to run more in the order I am expecting.

// .....
.then(function(){
   console.log("[2.1]");

   // create a deferred promise
   var deferred = Q.defer();

   require(['home/app/init'], function(app) {
      // we are inside the require function
      console.log("[2.2]");
      // run the actual method
      new app.init().wiring();
      // report back to the console.
      console.log("[2.3]");
      // resolve the promise
      deferred.resolve();
   });

   console.log("[2.4]");

   Q.when(deferred.promise).then(function() {
      console.log("[2.5]");
   }).then(function(){
      // ... continue
});

This at least seems to cause the code to pause and wait for the require to finish before it goes on to 2.5, but I'm not sure if this is the correct way to do this with Q.js.

Upvotes: 0

Views: 119

Answers (1)

Hargrovm
Hargrovm

Reputation: 1063

2.1 will run before 2.2 because that's the order you are running the code but the 2.2 code runs asynchronously so gets run once require has got everything in order which will take more time than it takes the 2.3 code to execute

I think in your second block of code you want to move the 2.2.2 block inside the when see the documentation for when at the bottom of this page https://github.com/kriskowal/q

Upvotes: 1

Related Questions