How to force javascript?

I found quite complex answers related to classes, event handlers, and callbacks (which seem a bit sledgehammer to me). I think callbacks might be useful, but I can't apply them in the simplest context. See this example:

<html> <head> <script type="text/javascript"> function myfunction() { longfunctionfirst(); shortfunctionsecond(); } function longfunctionfirst() { setTimeout('alert("first function finished");',3000); } function shortfunctionsecond() { setTimeout('alert("second function finished");',200); } </script> </head> <body> <a href="#" onclick="javascript:myfunction();return false;">Call my function</a> </body> </html> 

In this, the second function ends before the first function; what is the easiest way (or is there one?) to force the second function to delay execution until the first function is completed?

--- Edit ---

So, this was an example of garbage, but thanks to David Hedlund, I see in this new example that it is really synchronous (along with the failure of my browser during testing!):

 <html> <head> <script type="text/javascript"> function myfunction() { longfunctionfirst(); shortfunctionsecond(); } function longfunctionfirst() { var j = 10000; for (var i=0; i<j; i++) { document.body.innerHTML += i; } alert("first function finished"); } function shortfunctionsecond() { var j = 10; for (var i=0; i<j; i++) { document.body.innerHTML += i; } alert("second function finished"); } </script> </head> <body> <a href="#" onclick="javascript:myfunction();return false;">Call my function</a> </body> </html> 

As my ACTUAL problem was with jQuery and IE, I will have to post a separate question about it if I can’t get myself anywhere!

+61
javascript asynchronous callback synchronous execution
Dec 07 '09 at 10:36
source share
10 answers

Well, setTimeout , by its definition, will not hold the stream. This is desirable because if this happened, it would freeze the entire user interface while waiting. if you really need to use setTimeout , then you should use the callback functions:

 function myfunction() { longfunctionfirst(shortfunctionsecond); } function longfunctionfirst(callback) { setTimeout(function() { alert('first function finished'); if(typeof callback == 'function') callback(); }, 3000); }; function shortfunctionsecond() { setTimeout('alert("second function finished");', 200); }; 

If you do not use setTimeout , but simply perform functions that take a very long time and used setTimeout to simulate this, then your functions will be virtually synchronous and you would not have this problem at all. It should be noted, however, that AJAX requests are asynchronous and will, like setTimeout , not hold the UI thread until it finishes. With AJAX, like with setTimeout , you have to work with callbacks.

+44
Dec 07 '09 at 10:43
source share

I come back to these questions after all this time because it took me so long to find what I consider to be a clean solution: The only way to get javascript to execute sequentially, which I know, is to use promises. Comprehensive explanations exist for promises at: Promises / A and Promises / A +

The only library that implements promises that I know is jquery, so I would like to resolve the issue using jquery promises:

 <html> <head> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script type="text/javascript"> function myfunction() { promise = longfunctionfirst().then(shortfunctionsecond); } function longfunctionfirst() { d = new $.Deferred(); setTimeout('alert("first function finished");d.resolve()',3000); return d.promise() } function shortfunctionsecond() { d = new $.Deferred(); setTimeout('alert("second function finished");d.resolve()',200); return d.promise() } </script> </head> <body> <a href="#" onclick="javascript:myfunction();return false;">Call my function</a> </body> </html> 

By keeping a promise and associating functions with .then (), you guarantee that the second function will be executed only after the first executes. This is the d.resolve () command in longfunctionfirst (), which gives a signal to start the next function.

Technically, shortfunctionsecond () does not need to create deferred and return a promise, but I fell in love with promises and try to implement everything with promises, sorry.

+30
Aug 20 '13 at 12:23
source share

I am an old hand in programming and recently returned to my old passion and try my best to fit into this object-oriented, event-driven vibrant new world, and although I see the benefits of unclassified Javascript behavior, there is a time when it really hinders simplicity and reusability . A simple example I was working on was to take a snapshot (mobile phone programmed in javascript, HTML, phonegap, ...), resize it and upload it to the website. Perfect sequence:

  • Take a picture
  • Upload photo to img element
  • Resize image (using Pixastic)
  • Upload it to the website
  • Inform user about success error

All this would be a very simple sequential program if each step would return control to the next when it is finished, but in fact:

  • Make the photo asynchronous, so the program tries to load it into the img element before it exists
  • Upload the photo asynchronously so that the resize image starts before img is fully loaded.
  • Resizing is asynchronous, so uploading to a website starts before the image is fully resized.
  • Upload to the website - asyn so that the program continues until the photo is fully downloaded.

And btw 4 out of 5 steps include callback functions.

My solution this way is to put every step in the previous one and use .onload and other similar tricks. It looks something like this:

 takeAPhoto(takeaphotocallback(photo) { photo.onload = function () { resizePhoto(photo, resizePhotoCallback(photo) { uploadPhoto(photo, uploadPhotoCallback(status) { informUserOnOutcome(); }); }); }; loadPhoto(photo); }); 

(I hope I haven’t made too many mistakes by introducing code into this, which is real, just too distracting)

I think this is a great example, where async is not good, and synchronization is good, because contrary to the processing of Ui events, we should have every step before the next one is executed, but the code is a Russian doll, it confuses and unreadable, reuse The code is difficult to achieve because of all the nesting, it is simply difficult to bring all the necessary parameters to the internal function without passing them to each container in turn or using evil global variables, and I would love that the result of all this code will give me a return code, but not vy container will be completed well before the return code will be available.

Now, to get back to Tom’s first question, what would be smart, easy to read and easy reuse of what would be a very simple program 15 years ago using let say C and a dumb electronic board?

The requirement is actually so simple that I have the impression that I should miss the fundamental understanding of Javsascript and modern programming. Of course, is technology designed to increase labor productivity?

Thank you for your patience

Raymond Dinosaur; -)

+11
Oct 22 2018-10-10T00:
source share

There is no way in javascript to make the code wait. I had this problem, and the way I did it was a synchronous SJAX call to the server, and the server actually does sleep mode or does some activity before returning and all the time, js waits.

For example, Sync AJAX: http://www.hunlock.com/blogs/Snippets:_Synchronous_AJAX

+1
Dec 07 '09 at 10:42
source share

In your example, the first function actually ends before the second function starts. setTimeout does not execute the function until the timeout is reached, it just starts the timer in the background and executes your alert statement after the specified time.

JavaScript does not have its own way of doing a "dream". You can write a loop that checks the time, but it will put a lot of effort on the client. You can also make a synchronous AJAX call as described by emacsian, but this will add extra load to your server. This is best done to avoid this, which should be simple enough for most cases, once you understand how setTimeout works.

+1
Dec 07 '09 at 10:50
source share

I tried the callback and could not get this to work, what you should understand is that the values ​​are still atomic, although the execution is not executed. For example:

alert('1'); <--- these two functions will be executed simultaneously

alert('2'); <--- these two functions will be executed simultaneously

but this will make us know the execution order:

 loop=2; total=0; for(i=0;i<loop;i++) { total+=1; if(total == loop) alert('2'); else alert('1'); } 
+1
May 21 '11 at 23:03
source share

If you don't insist on using pure Javascript, you can create consistent code in Livescript, and that looks pretty good . You might want to take a look at this example :

 # application do i = 3 console.log td!, "start" <- :lo(op) -> console.log td!, "hi #{i}" i-- <- wait-for \something if i is 0 return op! # break lo(op) <- sleep 1500ms <- :lo(op) -> console.log td!, "hello #{i}" i++ if i is 3 return op! # break <- sleep 1000ms lo(op) <- sleep 0 console.log td!, "heyy" do a = 8 <- :lo(op) -> console.log td!, "this runs in parallel!", a a-- go \something if a is 0 return op! # break <- sleep 500ms lo(op) 

Exit:

 0ms : start 2ms : hi 3 3ms : this runs in parallel! 8 3ms : hi 2 505ms : this runs in parallel! 7 505ms : hi 1 1007ms : this runs in parallel! 6 1508ms : this runs in parallel! 5 2009ms : this runs in parallel! 4 2509ms : hello 0 2509ms : this runs in parallel! 3 3010ms : this runs in parallel! 2 3509ms : hello 1 3510ms : this runs in parallel! 1 4511ms : hello 2 4511ms : heyy 
+1
Apr 17 '16 at 4:32
source share

I had the same problem, this is my solution:

 var functionsToCall = new Array(); function f1() { $.ajax({ type:"POST", url: "/some/url", success: function(data) { doSomethingWith(data); //When done, call the next function.. callAFunction("parameter"); } }); } function f2() { /*...*/ callAFunction("parameter2"); } function f3() { /*...*/ callAFunction("parameter3"); } function f4() { /*...*/ callAFunction("parameter4"); } function f5() { /*...*/ callAFunction("parameter5"); } function f6() { /*...*/ callAFunction("parameter6"); } function f7() { /*...*/ callAFunction("parameter7"); } function f8() { /*...*/ callAFunction("parameter8"); } function f9() { /*...*/ callAFunction("parameter9"); } function callAllFunctionsSy(params) { functionsToCall.push(f1); functionsToCall.push(f2); functionsToCall.push(f3); functionsToCall.push(f4); functionsToCall.push(f5); functionsToCall.push(f6); functionsToCall.push(f7); functionsToCall.push(f8); functionsToCall.push(f9); functionsToCall.reverse(); callAFunction(params); } function callAFunction(params) { if (functionsToCall.length > 0) { var f=functionsToCall.pop(); f(params); } } 
+1
Jun 01 '16 at 2:59
source share

Another way to look at this is to chain from one function to another. Have an array of functions that is global for all of your called functions, for example:

 arrf: [ f_final ,f ,another_f ,f_again ], 

Then tune the array of integers to the specific 'f' you want to run, for example

 var runorder = [1,3,2,0]; 

Then call the initial function with "runorder" as a parameter, for example. f_start (runorder);

Then at the end of each function, simply put the index in the next "f" to execute the debugger and execute it, still passing the "runorder" as a parameter, but with a reduced array of one.

 var nextf = runorder.shift(); arrf[nextf].call(runorder); 

Obviously, this ends with a function, for example, with index 0, which is not tied to another function. This is completely determinate, avoiding "timers".

0
Aug 13 '16 at 13:38 on
source share

Put your code on the line, iterate, eval, setTimeout and recursion to continue working with the remaining lines. Without a doubt, I will clarify this or just throw it out if it does not reach the goal. I intend to use it to simulate really, really basic user testing.

Recursion and setTimeout make it consistent.

Thoughts?

 var line_pos = 0; var string =' console.log('123'); console.log('line pos is '+ line_pos); SLEEP console.log('waited'); console.log('line pos is '+ line_pos); SLEEP SLEEP console.log('Did i finish?'); '; var lines = string.split("\n"); var r = function(line_pos){ for (i = p; i < lines.length; i++) { if(lines[i] == 'SLEEP'){ setTimeout(function(){r(line_pos+1)},1500); return; } eval (lines[line_pos]); } console.log('COMPLETED READING LINES'); return; } console.log('STARTED READING LINES'); r.call(this,line_pos); 

EXIT

 STARTED READING LINES 123 124 1 p is 0 undefined waited p is 5 125 Did i finish? COMPLETED READING LINES 
0
May 10 '18 at 5:55
source share



All Articles