Synchronuns call function one by one
While there are likely better options, and this option gets messy quickly, you can pass the next function in as a parameter.
Be careful with brackets () in this scenario.
function func() < foo(function() < bar(function() < baz(); >) >) > function foo(callback) < setTimeout(function() < console.log("foo"); if (callback != null) callback(); >, 3000); > function bar(callback) < setTimeout(function() < console.log("bar"); if (callback != null) callback(); >, 3000); > function baz(callback) < setTimeout(function() < console.log("baz"); if (callback != null) callback(); >, 3000); > func()
If you don’t have any async code, then they will always run in sequence (synchronously). I’m guessing you have an ajax call or similar?
function func() < foo(); >var timer; function foo() < timer = setTimeout(function() < console.log("foo"); setTimeout(function() < console.log("bar"); setTimeout(function() < console.log("baz"); >, 3000); >, 3000); >, 3000); //alert("foo"); console.log('comes first'); > func();
Thanks for Help. My issue is I want to call function one by one without timeout. In first function I do some code after that execution I need to call second function. Is it possible?
Here is another approach. Use generator functions.
NOTE: This run function is grabbed from awync and simplfilized .
const GF = function*()<>; GF.constructor.prototype.run = function(cb)< run(this, cb); >; function run(genFunc, complete) < var rootObj = genFunc(); function exit(result) < if(typeof complete === 'function')< complete(result, rootObj); >> function processYieldResult(yielded, genObj, prev, next) < if(yielded.done)< if(genObj.cb) < return genObj.cb(prev); >if(genObj === rootObj) < return exit(prev); >return; > if(yielded.value instanceof Promise)< return yielded.value.then( function (result) < setTimeout(next, 0, result); >, function (err) < if(!(err instanceof Error))< err = new Error(err); >setTimeout(next, 0, err); > ); > next(yielded.value); > function doRun(genObj, cb, prevResult) < genObj.cb = cb; function next(prev) < if(prev instanceof Error)< return exit(prev); >var yielded; try< yielded = genObj.next(prev); >catch (err) < return exit(err); >processYieldResult(yielded, genObj, prev, next); > if(!prevResult) < next(); >else < processYieldResult(prevResult, genObj, void 0, next); >> return doRun(rootObj); > function foo() < return new Promise(resolve =>< setTimeout(function()< console.log("foo"); resolve(); >, 1000); >); > function bar() < return new Promise(resolve =>< setTimeout(function()< console.log("bar"); resolve(); >, 1000); >); > function baz() < return new Promise(resolve =>< setTimeout(function()< console.log("baz"); resolve(); >, 1000); >); > function *func() < yield foo(); yield bar(); yield baz(); >func.run();
Node.js — Execute functions one by one
I am trying to run these functions one by one, after it will execute first function move to second one and so on .. now it will render both functions at the same time, it is taking so much memory when there are over 3000 functions.
webshot('google.com', 'google.jpeg', options, function(err) <>); webshot('yahoo.com', 'yahoo.jpeg', options, function(err) <>);
it will take thumbnail of google and then of yahoo ..now it is takins taking both thumbnails at the same time. I want to take google thumbnail and after that take yahoo thumbnail ..not at the same time
Are these independent pages that your taking screenshots of? Are are these multiple pages on the same domain?
2 Answers 2
That last argument to each of those is called a «callback;» it gets called when the work has been finished. So if you want to do these one at a time, put the call to the next one inside the callback of the previous one:
webshot('google.com', 'google.jpeg', options, function(err) < webshot('yahoo.com', 'yahoo.jpeg', options, function(err) <>); >);
Of course, if you have a bunch of these (you mentioned 3000!), you’re not just going to nest them like that. I would probably create an array of the arguments you want to pass them, and then use a callback loop:
function process(list, callback) < var index = 0; doOne(); function doOne() < var entry = list[index++]; webshot(entry.domain, entry.img, entry.options, function(err) < // . error handling, etc. if (index < list.length) < doOne(); >else < callback(); >>); > > var webshots = [ , , // . ]; process(webshots, function() < // All done >);
Side note: This would be a bit cleaner with Promises. There are various libraries that will promise-ify Node-style callback APIs (like webshot’s), you might look at doing that.
If you did, you could handle those promises like this:
var webshots = [ , , // . ]; allDone = webshots.reduce(function(p, entry) < return p.then(function() < return promisifiedWebshot(entry.domain, entry.img, entry.options); >); >, Promise.resolve()); allDone.then(function() < // All done >) .catch(function() < // Handle error >);
functions in one by one order worked simultaneously in javascript
I am new to javascript and observed that the 2 functions in body tag onload=»expand();fadeOut();» at link http://jsfiddle.net/ankur3291/F8pXj/6/ are in serial order so must be executed one by one, but when seeing the result it seems that both the functions are running simultaneously. Why is it so? Why not they execute one by one serially? (plz do not try to update the code at specified link. because the link will then change) Also see the code below:
body .box #container #contain Unicorn
2 Answers 2
This is due to the way that setInterval works. Both functions set an interval that is to be called every millisecond (although it’s highly likely it will actually be called less frequently).
In your example, both functions schedule their update functions to be run using setInterval . The functions defined in the onload attribute of the body tag are called sequentially; however, the chunking of the animations into small pieces makes it look like they are run in parallel which is never the case due to JavaScript’s inherent single-threaded nature.
As a very broad rule of thumb, you can compare the way this works to a single-threaded process scheduler which alternates between several processes very quickly. Only one process runs at any given moment, but the frequent changing of the active process creates the illusion of parallelism.
Execute Function One by One
they will be all executed in the same time. How can I call them one by one so step2(); is called after step1(); is finished and step3(); is called after step2(); is finished. // MORE INFO Step1() is executing a json and appends details to html, Step2() is executing another json and appends info in the divs created by Step1() and Step3() simply hides a loading animation. // THE FUNCTIONS As requested by some users, here are the functions:
They will be executed sequentially since JavaScript is single-threaded. Or, at least what people commonly make use of. Can you tell us more about what is being run in those functions?
Step1() is executing a json and appends details to html, Step2() is executing another json and appends info in the divs created by Step1() and Step3() simply hides a loading animation.
2 Answers 2
Not knowing what you are executing in each function, I’m assuming none of them executes an asynchronous call themselves, i.e: ajax request and so on.
Should you have additional asynchronous calls occur in each function the below would not apply as is.
One option would be to use call one from the other similar to this:
function step1() < //. step2(); >function step2() < //. step3(); >function step3() < //. >
or you can use callbacks in the function signature, similar to this:
//pass step2 function as parameter to step1 //pass step3 function as parameter to step2 step1(step2(step3)); function step1(callback) < //. callback(); >function step2(callback) < //. callback(); >function step3() < //. >
Or using jQuery deferred might work, similar to this:
$.when($.when(step1()).then(step2)).then(step3);
I’m not 100% sure on the deferred solution using .when() .
The code above seems to work (DEMO) using when() but as FelixKing mentioned in the comments if you update the methods to return a deferred promise you can do this:
Each deferred object must be resolved() though for the next method to be executed.
This would also give you some control if you have a scenario for example in which you don’t want to execute step3() if step2() fails to do something and calls .reject() for instance.Have a play around with the deferred objects in the fiddle and have a look at the deferred promise documentation too for more details.
step1().then(step2).then(step3); function step1() < var $dfStep1 = new $.Deferred(); console.log("step1"); $dfStep1.resolve(); return $dfStep1.promise(); >function step2() < var $dfStep2 = new $.Deferred(); console.log("step2"); $dfStep2.resolve(); return $dfStep2.promise(); >function step3()
You don’t need $.when in this case. step1().then(step2).then(step3) should work fine if they all return deferred objects, promises.
Tried the ‘step1().then(step2).then(step3)’ and step3() never gets to get called. Console Error: Uncaught TypeError: Cannot call method ‘then’ of undefined
@Andrei: As FelixKing mentioned, the function have to return a promise() for you to be able to link them with then() . Otherwise you get that error.
If there is no asynchronous behaviour within the functions then they will be called sequentially. You may be seeing output in the console at different times than you expect, I believe consoles in firefox etc buffer output and can in some cases (although not very often) be misleading.
If you do have asynchronous behaviour within these functions then you either need to make it synchronous or put the call to function2 in the callback to function1 and function3 in the callback to function2. This will ensure that function2 is only called once function1 has reached an apropriate state.
Linked
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.17.43537
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.