issue in synchronized function execution in javascript - javascript

i am trying to sync three functions which have AJAX calls in them.
main(){
compileTemplate();
}
compileTemplate(){
func1();
func2();
func3();
}
each func has structure like :
func(){
$.when($.get(url)).then(func(d)
{//do something});
Each func() is completing on its own. i need when func1 completes then func2 should start.
checked
$.when(func1()).then(func2());
but its not working. please do anyone has any idea.

Make sure that the return value of func1, func2 and func3 are promises:
function func1() {
var d = new $.Deffered();
setTimeout(function () {
d.resolve();
}, 1000);
return d.promise();
}
function func2() {
return $.ajax(/* .. */);
}
function func3() {
return /* etc */
}
Then you can:
$.when(func1()).then(func2).then(func3); // notice the () or lack thereof
Or:
$.when(func1()).then(function () {
return func2();
}).then(function () {
return func3();
});
If you don't know whether func1, func2 and func3 will always return a promise this will still work, but you can not wait for it.
If you do:
$.when(func1()).then(func2()).then(func3());
func1, func2 add func3 will be called immediately, rather than serially. This is equvalent to:
var a = func1();
var b = func2();
var c = func3();
$.when(a).then(b).then(c);
//or
$.when(a, b, c);

function func1() {
if (ajaxObject.readyState == 4 && ajaxObject.status == 200) {
ajaxObject.onreadystatechange = func2;
ajaxObject.send();
}
}
function func2() {
if (ajaxObject.readyState == 4 && ajaxObject.status == 200) {
ajaxObject.onreadystatechange = func3;
ajaxObject.send();
}
function func3() {
}

Related

How to call a different function after completion of one function?

I have written long code, trying to replicate the situation in simple form by this simple code.
What I want to do is after function A() completion, call function B().
I am trying with callback function but in this case, B fired early.
Please suggest how can I write this callback or any other approach?
function A(callback){
a()
function a() {
setTimeout(aa,1000)
function aa(){
console.log("in aa")
}
}
b()
function b() {
setTimeout(bb,100)
function bb(){
console.log("in bb")
}
}
c()
function c(){
setTimeout(cc,50)
function cc(){
console.log("in cc")
}
}
callback();
}
function B() {
console.log("in B");
}
A(B)
output
in B
in cc
in bb
in aa
If you want your callback to run after a timeout has finished, then you have to call it when the timeout has finished.
And that means it needs to be at the end of the function you pass to setTimeout.
With your current code, you are setting the countdown on the timeout going and then immediately calling the callback.
function one(callback) {
console.log(1);
function two() {
console.log(2);
callback();
}
setTimeout(two, 250);
}
function three() {
console.log(3);
}
one(three);
Essentially, what's happening here (as you requested) is that you want B to run after A is completed.
There is no need to use "B" as a callback, with async/await.
B will wait till A is completed before it's called.
const b = () => {
return new Promise((resolve, reject)=>{
setTimeout(()=>{resolve("B done")}, 1000);
});
}
const c = () => {
return new Promise((resolve, reject)=>{
setTimeout(()=>{resolve("C done")}, 500);
});
}
const A = async () => {
const bres = await b();
console.log(bres);
const cres = await c();
console.log(cres);
};
const B = async () => {
console.log("done");
}
const app = async() => {
await A();
await B();
};
app();

Can a javascript function run in setTimeout callback only?

This is the question:
Define a function named print which just print out the parameters it gets.
But it will not print out anything if it's called normally.
Only in a setTimeout callback will become effective.
e.g:
setTimeout(function() {
print('123'); //===> 123
});
print('456'); //===> nothing output
I have one solution but I don't think it's a good way, I rewrite the setTimeout.
I want a better solution curiously.
var print = function() {
'use strict';
var __origSetTimeout = window.setTimeout;
window.setTimeout = function(fn, delay) {
var _fn = new Function(`(${fn.toString().replace(/print\(/g, 'print.call(this,')}).call(this);`);
return __origSetTimeout.call(window, _fn.bind({
isFromSetTimeout: true
}), delay);
};
return function print(word) {
if (!this || !!this && !this.isFromSetTimeout) return;
console.log(word);
};
}.call(null);
You can use scope to solve this, for example
function A(){
let print = function(str){
console.log(str);
}
this.setTimeout = function(){
setTimeout(function(){
print('123');
}, 1000);
}
}
let a = new A();
a.setTimeout();
You could use a monkey patch for an extension of the print function with an additional check for a this object and a property for printing.
// simple function with output
function print(s) {
console.log(s);
}
// apply monkey patch
void function () {
var p = print;
print = function () {
if (this && this.timeout) {
p.apply(this, arguments);
}
}
}();
// bind additional information
setTimeout(print.bind({ timeout: true }, '123'));
print('456');

Asynchronous execution of functions in javascript

I want to call two function say function a() and function b() in parallel. These functions are independent to each other, and lets say the time required to execute these two functions are not fixed. Sometimes function a() will take more time than function b() and vice versa. But there is another function c() that should only execute when both the functions a() and b() are completed.
How should I do this using jQuery's Deferred object?
To achieve this you can make the a() and b() functions return deferred objects which you resolve() once their logic has completed. You can then run c() once both previous functions have completed. Try this:
function a() {
var aDef = $.Deferred();
setTimeout(function() {
aDef.resolve('a done');
}, 1000);
return aDef;
}
function b() {
var bDef = $.Deferred();
setTimeout(function() {
bDef.resolve('b done');
}, 3000);
return bDef;
}
function c() {
console.log('all done!')
}
console.log('running...');
$.when(a(), b()).done(function(a, b) {
console.log(a);
console.log(b);
c();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I'd use a global variable to determ an operational status and execute a polling each 100 milliseconds (or each milliseconds if you need).
var myStatus = {
"a": false,
"b": false
};
function a() {
myStatus["a"] = true;
console.log(myStatus['a']);
}
function b() {
myStatus["b"] = true;
}
function getStatusText() {
var s = 'not complete';
if (myStatus.a && myStatus.b) {
s = 'all complete';
} else {
if (myStatus.a) {
s = 'a complete';
}
if (myStatus.b) {
s = 'b complete';
}
}
return s;
}
function c() {
//check operational status
var statusText = getStatusText();
document.getElementById('status').innerHTML = statusText;
}
setInterval(
function() {
c()
}, 100);
<button onclick="a()">Set a() complete</button><button onclick="b()">Set b() complete</button>
<p>operational status <span id="status"></span></p>
Please refer Jquery defer and promise method to handle calls.
https://api.jquery.com/deferred.promise/ or
https://api.jquery.com/promise/
This is not exactly an answer to the question. I don't use defer or anything like it.
But I want to show something I do quite often: add a onReady callback, as a parameter to a() and b(). I add these callbacks to any self-written-function that takes time to execute.
function a(onready) {
// let's say we get Ajax data
$.ajax({
url: 'data.php',
success: function(data) {
$('#message').html(data);
if(typeof onready == 'function') {
onready(); // you might also want to add message as a parameter, like onready(data), or anready('Data okay'), ...
}
}
});
}
function b(onready) {
// let's say we sort <table> rows
sortTable('my_table', 'my_row', 'ASC'); // this function (not provided here) is not asynchronous, it just takes time before it's done
if(typeof onready == 'function') {
onready();
}
}
function c() {
alert('Yippy!');
}
$(document).ready(function() { // or this could be after the client clicks on a button, or so
var aReady = false;
var bReady = false;
a(function() {
aReady = true;
if(aReady && bReady) {
c();
}
});
b(function() {
bReady = true;
if(aReady && bReady) {
c();
}
});
});
You can use jQuery.when() to do this. Please read the document about this at https://api.jquery.com/jquery.when/
a = function () {
//your code for function a
}
b = function () {
//your code for function b
}
$.when( a(), b() ).done(function c() {
//your code for function c
});

Async transactions in javascript

First of all rollback is something that I do not care about.
I would like to be able to lock a sequence of async functions/promises/tasks (let's call it a "transaction") with a name/id (or array of names), so that they happen in sequence, and so that any other "transaction" with the same name(s) that are run by another part of the system are delayed from starting until the running transaction using the same name(s) has completed. So it basically is queueing the sequences of async tasks, or "transaction"s.
Here is some example code of the situation:
function a()
{
// do stuff
return new Promise(/*...*/);
}
function b()
{
// do stuff
return new Promise(/*...*/);
}
function c()
{
// do stuff
return a.then(() => b());
}
Now at any time the system could call a, b, or c, and when it does I don't want c and b running at the same time, but obvious c depends on b.
I've been looking for a package on npm to help with this but I haven't found anything, I wonder if anyone can suggest something that I might have missed that would help with this?
I think gulp tasks can help you out of the box. This guarantees that c always run after b and so b after a
const gulp = require('gulp');
gulp.task('a', done => {
// do stuff
console.log('a');
done();
});
gulp.task('b', ['a'], done => {
// do stuff
console.log('b');
done();
});
gulp.task('c', ['b'], done => {
// do more stuff
console.log('c');
done();
});
gulp.start('c'); // Logs a, b, c
Try it!
You could write your own little transaction manager.
const transactions = {};
function doTransaction(name, promiseFunc) {
transactions[name] = (transactions[name] || Promise.resolve()).then(promiseFunc);
}
Use async/await and have babel transpile it. Async Babel Docs
function a()
{
// do stuff
return new Promise(/*...*/);
}
async function b()
{
const aData = await a();
// do stuff
return new Promise(/*...*/);
}
async function c()
{
const bData = await b();
// do stuff
return bData;
}
You can go for https://github.com/Reactive-Extensions/RxJS
They have many functions to handle single/multiple/dependent/parallel async calls.
function a()
{
// do stuff
return new Promise(/*...*/);
}
function b()
{
// do stuff
return new Promise(/*...*/);
}
function c()
{
// do stuff
return new Value;
}
a().then(function(data_a) {
// you can make use of return value (which is data_a) here or as an argument for function b or even function c
b().then(function(data_b) {
// you can make use of return value (which is data_b) here or as an argument for function c
c().then(function(data_c) {
// do your coding here
});
});
});
you can check this link for reference : https://spring.io/understanding/javascript-promises
Ok, here's my take.
You use a wrapper for your function b which returns and object with 2 methods: doCall and wait. The wrapper should be called only once.
doCall will call your function and trace its completion for the wait() function.
wait() will wait for the completion and always resolve when doCall() finishes
Now for the code, also on CodePen (see developer console):
function wrapPromiseFn(fn) {
var prev = null;
var doCall = function() {
var retValue;
prev = new Promise(function(resolve, reject) {
retValue = fn();
retValue.then(function(result) {
resolve(true);
});
retValue.catch(function(result) {
resolve(true);
});
});
return retValue;
};
var wait = function() {
return prev ? prev : Promise.resolve(false);
};
return {
doCall: doCall,
wait: wait
};
}
function a() {
return Promise.resolve(42);
}
function b() {
//return Promise.reject(new Date());
return Promise.resolve(new Date().getTime());
}
var wrappedB = wrapPromiseFn(b);
function doStuff() {
return wrappedB.wait().then(function(didWait) {
return a().then(function(_a) {
return wrappedB.doCall().then(function(_b) {
console.log("didWait, a, b: ", didWait, _a, _b);
});
});
});
}
//run it twice to prove it did wait
doStuff().then(doStuff)
It proves the concept, of course it would need some polish to pass arguments from doCall to the wrapped function.

Function in JavaScript that can be called only once

I need to create a function which can be executed only once, in each time after the first it won't be executed. I know from C++ and Java about static variables that can do the work but I would like to know if there is a more elegant way to do this?
If by "won't be executed" you mean "will do nothing when called more than once", you can create a closure:
var something = (function() {
var executed = false;
return function() {
if (!executed) {
executed = true;
// do something
}
};
})();
something(); // "do something" happens
something(); // nothing happens
In answer to a comment by #Vladloffe (now deleted): With a global variable, other code could reset the value of the "executed" flag (whatever name you pick for it). With a closure, other code has no way to do that, either accidentally or deliberately.
As other answers here point out, several libraries (such as Underscore and Ramda) have a little utility function (typically named once()[*]) that accepts a function as an argument and returns another function that calls the supplied function exactly once, regardless of how many times the returned function is called. The returned function also caches the value first returned by the supplied function and returns that on subsequent calls.
However, if you aren't using such a third-party library, but still want a utility function (rather than the nonce solution I offered above), it's easy enough to implement. The nicest version I've seen is this one posted by David Walsh:
function once(fn, context) {
var result;
return function() {
if (fn) {
result = fn.apply(context || this, arguments);
fn = null;
}
return result;
};
}
I would be inclined to change fn = null; to fn = context = null;. There's no reason for the closure to maintain a reference to context once fn has been called.
Usage:
function something() { /* do something */ }
var one_something = once(something);
one_something(); // "do something" happens
one_something(); // nothing happens
[*] Be aware, though, that other libraries, such as this Drupal extension to jQuery, may have a function named once() that does something quite different.
Replace it with a reusable NOOP (no operation) function.
// this function does nothing
function noop() {};
function foo() {
foo = noop; // swap the functions
// do your thing
}
function bar() {
bar = noop; // swap the functions
// do your thing
}
Point to an empty function once it has been called:
function myFunc(){
myFunc = function(){}; // kill it as soon as it was called
console.log('call once and never again!'); // your stuff here
};
<button onClick=myFunc()>Call myFunc()</button>
Or, like so:
var myFunc = function func(){
if( myFunc.fired ) return;
myFunc.fired = true;
console.log('called once and never again!'); // your stuff here
};
// even if referenced & "renamed"
((refToMyfunc)=>{
setInterval(refToMyfunc, 1000);
})(myFunc)
UnderscoreJs has a function that does that, underscorejs.org/#once
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = function(func) {
var ran = false, memo;
return function() {
if (ran) return memo;
ran = true;
memo = func.apply(this, arguments);
func = null;
return memo;
};
};
Talking about static variables, this is a little bit like closure variant:
var once = function() {
if(once.done) return;
console.log('Doing this once!');
once.done = true;
};
once(); // Logs "Doing this once!"
once(); // Logs nothing
You could then reset a function if you wish:
once.done = false;
once(); // Logs "Doing this once!" again
You could simply have the function "remove itself"
​function Once(){
console.log("run");
Once = undefined;
}
Once(); // run
Once(); // Uncaught TypeError: undefined is not a function
But this may not be the best answer if you don't want to be swallowing errors.
You could also do this:
function Once(){
console.log("run");
Once = function(){};
}
Once(); // run
Once(); // nothing happens
I need it to work like smart pointer, if there no elements from type A it can be executed, if there is one or more A elements the function can't be executed.
function Conditional(){
if (!<no elements from type A>) return;
// do stuff
}
var quit = false;
function something() {
if(quit) {
return;
}
quit = true;
... other code....
}
simple decorator that easy to write when you need
function one(func) {
return function () {
func && func.apply(this, arguments);
func = null;
}
}
using:
var initializer= one( _ =>{
console.log('initializing')
})
initializer() // 'initializing'
initializer() // nop
initializer() // nop
try this
var fun = (function() {
var called = false;
return function() {
if (!called) {
console.log("I called");
called = true;
}
}
})()
From some dude named Crockford... :)
function once(func) {
return function () {
var f = func;
func = null;
return f.apply(
this,
arguments
);
};
}
Reusable invalidate function which works with setInterval:
var myFunc = function (){
if (invalidate(arguments)) return;
console.log('called once and never again!'); // your stuff here
};
const invalidate = function(a) {
var fired = a.callee.fired;
a.callee.fired = true;
return fired;
}
setInterval(myFunc, 1000);
Try it on JSBin: https://jsbin.com/vicipar/edit?js,console
Variation of answer from Bunyk
Here is an example JSFiddle - http://jsfiddle.net/6yL6t/
And the code:
function hashCode(str) {
var hash = 0, i, chr, len;
if (str.length == 0) return hash;
for (i = 0, len = str.length; i < len; i++) {
chr = str.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
var onceHashes = {};
function once(func) {
var unique = hashCode(func.toString().match(/function[^{]+\{([\s\S]*)\}$/)[1]);
if (!onceHashes[unique]) {
onceHashes[unique] = true;
func();
}
}
You could do:
for (var i=0; i<10; i++) {
once(function() {
alert(i);
});
}
And it will run only once :)
Initial setup:
var once = function( once_fn ) {
var ret, is_called;
// return new function which is our control function
// to make sure once_fn is only called once:
return function(arg1, arg2, arg3) {
if ( is_called ) return ret;
is_called = true;
// return the result from once_fn and store to so we can return it multiply times:
// you might wanna look at Function.prototype.apply:
ret = once_fn(arg1, arg2, arg3);
return ret;
};
}
If your using Node.js or writing JavaScript with browserify, consider the "once" npm module:
var once = require('once')
function load (file, cb) {
cb = once(cb)
loader.load('file')
loader.once('load', cb)
loader.once('error', cb)
}
If you want to be able to reuse the function in the future then this works well based on ed Hopp's code above (I realize that the original question didn't call for this extra feature!):
var something = (function() {
var executed = false;
return function(value) {
// if an argument is not present then
if(arguments.length == 0) {
if (!executed) {
executed = true;
//Do stuff here only once unless reset
console.log("Hello World!");
}
else return;
} else {
// otherwise allow the function to fire again
executed = value;
return;
}
}
})();
something();//Hello World!
something();
something();
console.log("Reset"); //Reset
something(false);
something();//Hello World!
something();
something();
The output look like:
Hello World!
Reset
Hello World!
A simple example for turning on light only once.
function turnOnLightOnce() {
let lightOn = false;
return function () {
if (!lightOn) {
console.log("Light is not on...Turning it on for first and last time");
lightOn = true;
}
};
}
const lightOn = turnOnLightOnce();
lightOn() // Light is not on...Turning it on for first and last time
lightOn()
lightOn()
lightOn()
lightOn()
https://codesandbox.io/s/javascript-forked-ojo0i?file=/index.js
This happens due to closure in JavaScript.
function once (fn1) {
var ran = false
var memo = null
var fn = function(...args) {
if(ran) {return memo}
ran = true
memo = fn1.apply(null, args)
return memo
}
return fn
}
I'm using typescript with node and it was #I Hate Lazy's answer that inspired me. I just assigned my function to a noop function.
let printName = (name: string) => {
console.log(name)
printName = () => {}
}
printName('Sophia') // Sophia
printName('Nico') // Nothing Happens
https://jsbin.com/yuzicek/edit?js,console
FOR EVENT HANDLER
If the function is a callback for an event listener, there is already a built-in option in the addEventListner method for just executing the callback once.
It can accept 3 parameters
Type
callback
options
options is an object that has a property called once
ex:
const button = document.getElementById('button');
const callbackFunc = () => {
alert('run')
}
button.addEventListener('click', callbackFunc, { once: true })
<button id="button">Click Once</button>
Trying to use underscore "once" function:
var initialize = _.once(createApplication);
initialize();
initialize();
// Application is only created once.
http://underscorejs.org/#once
var init = function() {
console.log("logges only once");
init = false;
};
if(init) { init(); }
/* next time executing init() will cause error because now init is
-equal to false, thus typing init will return false; */
if (!window.doesThisOnce){
function myFunction() {
// do something
window.doesThisOnce = true;
};
};
If you're using Ramda, you can use the function "once".
A quote from the documentation:
once Function
(a… → b) → (a… → b)
PARAMETERS
Added in v0.1.0
Accepts a function fn and returns a function that guards invocation of fn such that fn can only ever be called once, no matter how many times the returned function is invoked. The first value calculated is returned in subsequent invocations.
var addOneOnce = R.once(x => x + 1);
addOneOnce(10); //=> 11
addOneOnce(addOneOnce(50)); //=> 11
keep it as simple as possible
function sree(){
console.log('hey');
window.sree = _=>{};
}
You can see the result
JQuery allows to call the function only once using the method one():
let func = function() {
console.log('Calling just once!');
}
let elem = $('#example');
elem.one('click', func);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p>Function that can be called only once</p>
<button id="example" >JQuery one()</button>
</div>
Implementation using JQuery method on():
let func = function(e) {
console.log('Calling just once!');
$(e.target).off(e.type, func)
}
let elem = $('#example');
elem.on('click', func);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p>Function that can be called only once</p>
<button id="example" >JQuery on()</button>
</div>
Implementation using native JS:
let func = function(e) {
console.log('Calling just once!');
e.target.removeEventListener(e.type, func);
}
let elem = document.getElementById('example');
elem.addEventListener('click', func);
<div>
<p>Functions that can be called only once</p>
<button id="example" >ECMAScript addEventListener</button>
</div>
Tossing my hat in the ring for fun, added advantage of memoizing
const callOnce = (fn, i=0, memo) => () => i++ ? memo : (memo = fn());
// usage
const myExpensiveFunction = () => { return console.log('joe'),5; }
const memoed = callOnce(myExpensiveFunction);
memoed(); //logs "joe", returns 5
memoed(); // returns 5
memoed(); // returns 5
...
You can use IIFE. IIFE means Immediately Invoked Function Expression and the result is to call a function only once by the time is created.
Your code will be like this:
(function () {
//The code you want to execute only one time etc...
console.log("Hello world");
})()
Additionally, this way the data in the function remains encapsulated.
Of course and you can return values from the function and stored them into a new variable, by doing:
const/let value = (function () {
//The code you want to execute only one time etc...
const x = 10;
return x;
})()
function x()
{
let a=0;
return function check()
{
if(!a++)
{
console.log("This Function will execute Once.")
return;
}
console.log("You Can't Execute it For the Second Time.")
return;
}
}
z=x()
z() //Op - This Function will execute once
z() //OP - You can't Execute it for the second time.
I find it useful to just have a simple function that just returns true once, so you can keep the side effects higher up.
let once = () => !! (once = () => false);
once() // true
once() // false
Use like this:
if (once()) {
sideEffect()
}
This exploits the fact that you can coerce an assignment expression to return true while changing the same function into a function that returns false.
If you must have it execute a function, it can be adapted using a ternary:
let once = (x) => !! (once = () => false) ? x() : false;
Now it accepts a single function as an argument. Fun fact, the second false is never reached.
// This is how function in JavaScript can be called only once
let started = false;
if (!started) {
start() { // "do something" }
}
started = true;
}

Categories