Call a function after previous function is complete
Specify an anonymous callback, and make function1 accept it:
$('a.button').click(function(){
if (condition == 'true'){
function1(someVariable, function() {
function2(someOtherVariable);
});
}
else {
doThis(someVariable);
}
});
function function1(param, callback) {
...do stuff
callback();
}
Efficient way of executing 2 functions one after another in Javascript
There are a couple of ways you could approach this, the two most common ways would be using a callback, or using Promises.
Using CallbacksYou would add a callback argument to the first function, and then pass in function two as the callback:
function one(callback) {
setTimeout(function() {
console.log("first function executed");
callback();
}, 3000);
}
function two() {
console.log("second function executed");
}
one(two)
Javascript call function after another function executes
Well since it is an asynchronous task, you need to add logic to tell the next code when to run. Classic way is to use a a callback method:
function make_base(img, callback) {
base_image = new Image();
base_image.src = img;
base_image.onload = function(){
context.drawImage(base_image, 0, 0);
callback()
}
}
function text(text) {
context.fillText(text, 50, 50)
}
function render() {
make_base(xxx, function () {
text(xxx)
})
}
or move into modern patterns is to use a promise
function make_base(img) {
return new Promise(function(resolve, reject) {
base_image = new Image();
base_image.src = img;
base_image.onload = function(){
context.drawImage(base_image, 0, 0);
resolve()
}
}
function text(text) {
context.fillText(text, 50, 50)
}
function render() {
make_base(xxx).then(function () {
text(xxx)
})
}
How to execute 2 function after one another in Typescript?
Synchronous and asynchronous execution
If the functions are synchronous, you can just call them sequentially because they are executed one after another:
getStudentDataFunction()
getTeachersDataFunction()
However presumably the functions are asynchronous, otherwise you wouldn't have asked the question. That means one statement in that function must start the process of obtaining data, but it is obtained via another program path.
Example of an asynchronous request
One example of this would be XMLHttpRequest
, the standard way of making an in-browser HTTP request (the example is from Mozilla documentation):
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://www.example.org/example.txt");
oReq.send();
Here the oReq.send();
makes the HTTP request, starting the process of requesting data. But the way that data is actually obtained is via the use of the callback function reqListener
in the second line. When the data is ready, that function is separately called with a this
context object which allows the HTTP response to be obtained. So any code to be executed as a result of the HTTP request returning must be called from reqListener
.
Applying to your scenario
In order to get your functions to operate sequentially, you need to identify the the callback function or other mechanism getStudentDataFunction()
uses to obtain its data, and then use one of JavaScript's ways of handling asynchronous code to order the functions in the way you want. The three main ways are callbacks, Promises, and async functions (from oldest to most modern). getStudentDataFunction()
should itself be using one of those three methods.
These would work as follows:
// 1. If getStudentDataFunction() accepts a callback
var studentCallback = function(studentData) {
getTeachersDataFunction()
}
getStudentDataFunction(studentCallback)
// 2. If getStudentDataFunction() returns a Promise:
getStudentDataFunction()
.then(getTeachersDataFunction) // second function is only called when Promise resolves
// 3. If getStudentDataFunction() returns a Promise and you wish to use async functions:
async function getAllData() {
await getStudentDataFunction() // await keyword makes execution wait for Promise to resolve
getTeachersDataFunction()
}
getAllData()
How to execute function one after another?
Ideally you'd have to use some of the RxJS functions and operators at your disposal. And when it comes to observables,
- It's better to subscribe them where it's response is required
- Use as less subscriptions as possible
Given these, I'd make the following changes to your implementation.
initData1(): Observable<any> { // <-- return observable here
// use `forkJoin` function to trigger multiple observables in parallel
return forkJoin({
title: this.dataService.getTitleImageUrl(this.data.titlId, this.data.id),
contact: this.dataService.getTitleImageUrl(this.data.titlId, this.data.id)
}).pipe(
// use `tap` operator to perform side-effects
tap(imageUrls => {
this.titleImageUrl = encodeURI(imageUrls.title.results[0]);
this.contactImageUrl = encodeURI(imageUrls.contact.results[0]);
})
);
}
initData2(): Observable<any> { // <-- return observable here
// use `forkJoin` function to trigger multiple observables in parallel
return forkJoin({
title: this.dataService.getTitleImageUrl(this.data.titlId, this.data.id),
contact: this.dataService.getTitleImageUrl(this.data.titlId, this.data.id)
}).pipe(
// use `tap` operator to perform side-effects
tap(imageUrls => {
this.titleImageUrl = encodeURI(imageUrls.title.results[0]);
this.contactImageUrl = encodeURI(imageUrls.contact.results[0]);
})
);
}
And later you could use higher order mapping operator (for co-dependent) observables to map from one observable to another
ngOnInit() {
this.initData1().pipe(
switchMap(imageUrls => this.initData2())
).subscribe(
response => {
// response from `this.initData2()`
},
error => {
// handle errors
}
);
}
Further information on handling nested subscriptions here.
how to execute a function after another one
You could pass b
to a
as a callback and then call it inside of a
.
function a(cb) { $('.title').text('3'); cb()}
function b() { $('.title').eq(0).text('5');}
$('button').on('click', function() { a(b);});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='title'>title</div><div class='title'>title</div><div class='title'>title</div><div class='title'>title</div>
<button>CLICK</button>
Execute javascript function after previous one finishes
There's many different approaches to this but I would suggest using a Promise like this:
document.getElementById('btnSend').addEventListener('click', e => { e.preventDefault(); var result = validateInputs(email, subject, message); if(result){ showElement(document.getElementById('formGroupSpinner'), 2000).then(()=>{ return showElement(document.getElementById('formGroupSuccessImg'), 2000); }).then(()=>{ resetForm(); }); }});
//expects an html element and a number representing miliseconds. Shows the html element for that amount of time.function showElement(element, mSeconds) { return new Promise((resolve, reject) => { element.classList.remove('d-none'); element.classList.add('d-block'); setTimeout( () => { element.classList.remove('d-block'); element.classList.add('d-none'); resolve(); }, mSeconds); });}
Related Topics
Stringified Json Has Unwanted Double Quotes
Converting String Date in React/Javascript
How to Style HTML Select Option Hover and Selected Option Effects
How to Output a Pdf Buffer to Browser Using Nodejs
How to Only Trigger Parent Click Event When a Child Is Clicked
What's the Best Way to Reload/Refresh an Iframe
How to Hide Div When You Scroll to Bottom and Show It Again When Scroll Up to Top
Generate Pdf from HTML in Div Using JavaScript
How to Get a Div Element from an External Webpage in HTML File
Transforming Null into Empty String in JavaScript
How to Get the Name of the Current Windows User in JavaScript
React: Do Children Always Rerender When the Parent Component Rerenders
Changing the Value of Json Object's Key, Changes Other Values Also
How to Open a File/Browse Dialog Using JavaScript
How to Prevent Ajax Requests to Follow Redirects Using Jquery