I'm trying to understand callbacks and promises using very simple examples. I figured out how to rewrite an example of why you need callbacks into a working "callback form". However, I'm stuck on rewriting this into a promise
I have tried to make this work as a promise following the example here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Basic_Example
But I'm having some trouble making it work.
First I got this code showing why callbacks are important:
function first(){
// Simulate a code delay
setTimeout( function(){
console.log(1);
}, 500 );
}
function second(){
console.log(2);
}
first();
second();
I then rewrote this using callbacks:
function first(callback){
// Simulate a code delay
setTimeout( function(){
console.log(1);
callback();
}, 500 );
}
function second(){
console.log(2);
}
first(second);
// second();
Now I'm wondering how to rewrite this as a promise.
let first = new Promise( function (resolve, reject){
// Simulate a code delay
setTimeout( function(){
console.log(1);
resolve('success')
}, 500 );
});
function second(){
console.log(2);
}
first.then(second());
What I want it to output is first 1 and then 2, now it ouputs 2, then 1.
this is the code that should do what you're asking.
The problem in your code is that you're actually calling second() immediately:
first.then(second());
instead of passing the function as the argument (then() will call it when the first promise is resolved):
let first = new Promise( function (resolve, reject){
// Simulate a code delay
setTimeout( function(){
console.log(1);
resolve('success')
}, 500 );
});
function second(){
console.log(2);
}
first.then(second);
Related
Here is my function
function two(){
console.log('two')
}
function one(callback){
setTimeout(()=>{
console.log('one')
},2000)
callback()
}
one(two)
Actual output:
two
one
My expected Output:
one
two
My question is how to make changes to these functions so that function two() will be executed after function one()
You could simply call the callback() in your setTimeout's anonymous function like so:
function two() {
console.log('two')
}
function one(callback) {
setTimeout(() => {
console.log('one');
callback(); // execute callback after everything in setTimeout is executed
}, 2000);
}
one(two);
... or, instead, you can use a Promise with ES7's async/await (or using a .then() callback) capabilities like so:
function two() {
console.log('two')
}
async function one(callback) { // make async so we can use `await`
await new Promise((resolve, rej) => { // wait for the promise to resolve ...
setTimeout(() => {
console.log('one');
resolve();
}, 2000)
});
callback(); // ... then execute the callback
}
one(two);
This works
let one = new Promise((resolve, reject) =>{
setTimeout(()=>{
console.log('one')
resolve(true)
},2000)
})
one.then((value) => {
console.log('two')
})
I think callback will be called before other execution.This also works.
function two(){
console.log('two')
}
function one(one, callback){
console.log(one);
callback()
}
one('one', two);
In the Master.aspx I have some init code
app.asynInit(
getData();// this needs to execute first
)
And then in one of the custom control I have some logic
doSomethingLater() // this needs to wait for the getData()
I am not sure what is the best way to make sure doSomething() always execute after app.asynInit()
My current solution is to use jQuery's custom event.
app.asynInit() // this needs to execute first
$(document).trigger('initCompleted')
$(document).on('initCompleted',function(){ document() // this needs to wait for the getData()})
It appears to work. But is there any better alternatives? Should I use document here?
You can try to use Promise class:
var initAsync = function () {
var promise = new Promise(function (done) {
setTimeout(function () {
console.log('DONE');
done();
}, 3000);
});
return promise;
};
(async function () {
await initAsync();
console.log('continue...');
// doSomething();
}());
Source: Promise
If you're using this action on IE old version. You can use callback function:
var init = function (callback) {
setTimeout(function () {
console.log('DONE');
callback();
}, 3000);
};
init(function () {
console.log('continue...');
// doSomething();
});
I end up in with this implementation with the callback approach:
In Master.aspx:
app.asynInit(
getData();// this needs to execute first
window.isDataGet = true;
)
function onDataGet(cb){
if(window.isDataGet )
cb();
else
setTimeout(onDataGet,100)
}
In Custom Control:
onDataGet(//callback function here)
I want to know how to make setTimeout wait before executing what comes after.
setTimeout( function() { console.log("First"); }, 5000 );
console.log("Second");
In the console I want to see:
First
Second
"First" after 5 seconds and then "Second" just after "First"
But what's really happening is that I have "Second" and after 5 seconds "First"
How can this be fixed ?
If IE is not priority and you allowed to use Promise, then you can use a simple wait function to work as setTimeout and return Promisewhich allows for method chaining:
function wait(t) {
return new Promise(function(resolve) {
window.setTimeout(resolve, t)
});
}
wait(5000)
.then(function(){ console.log("First"); })
.then(function(){ console.log("Second"); });
setTimeout( function() { console.log("First"); }, 1000 );
setTimeout( function() { console.log("Second"); }, 1000 );
Javascript does not guarantee linear order of execution in your code. You can't expect your code to execute line by line when introducing timeouts or asynchronous tasks.
You could print both lines within the resolving function:
setTimeout(function() {
console.log("First");
console.log("Second");
}, 5000);
If you are executing more than just a console log after, you can write a new function to run after the setTimeout. Anything in the "second" function will occur after logging "First".
var second = function () {
console.log("Second");
}
setTimeout( function() {
console.log("First");
second();
}, 5000 );
I want to know how to make setTimeout wait before executing what comes after.
I think the JavaScript function for "wait" is setTimeout. Meaning you can achieve this by nesting one setTimeout function inside another.
setTimeout(function() {
setTimeout(function() {
console.log('Second');
}, 100);
console.log('First');
}, 5000);
I have two functions
function one() {
setTimeout(function(){ console.log("first function executed"); }, 3000);
}
function two() {
console.log("second function executed");
}
How can i let second function waits till first function executed? What is the easiest way for a beginner? Thanx
There are a couple of ways you could approach this, the two most common ways would be using a callback, or using Promises.
Using Callbacks
You 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)
Using Promises:
Promises allow you to chain different actions together that are dependant on ordering. However, you may need to add polyfills to support older browsers:
function one() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log("first function executed");
resolve();
}, 3000);
})
}
function two() {
console.log("second function executed");
}
one().then(two)
I have the following scenario:
setTimeout("alert('this alert is timedout and should be the first');", 5000);
alert("this should be the second one");
I need the code after the setTimeout to be executed after the code in the setTimeout is executed. Since the code that comes after the setTimeout is not code of my own I can't put it in the function called in the setTimeout...
Is there any way around this?
Is the code contained in a function?
function test() {
setTimeout(...);
// code that you cannot modify?
}
In that case, you could prevent the function from further execution, and then run it again:
function test(flag) {
if(!flag) {
setTimeout(function() {
alert();
test(true);
}, 5000);
return;
}
// code that you cannot modify
}
I came in a situation where I needed a similar functionality last week and it made me think of this post. Basically I think the "Busy Waiting" to which #AndreKR refers, would be a suitable solution in a lot of situations. Below is the code I used to hog up the browser and force a wait condition.
function pause(milliseconds) {
var dt = new Date();
while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
}
document.write("first statement");
alert("first statement");
pause(3000);
document.write("<br />3 seconds");
alert("paused for 3 seconds");
Keep in mind that this code acutally holds up your browser.
Hope it helps anyone.
Using ES6 & promises & async you can achieve running things synchronously.
So what is the code doing?
1. Calls setTimeOut 1st inside of demo then put it into the webApi Stack
2. Creates a promise from the sleep function using the setTimeout, then resolves after the timeout has been completed;
3. By then, the first setTimeout will reach its timer and execute from webApi stack.
4. Then following, the remaining alert will show up.
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function demo() {
setTimeout("alert('this alert is timedout and should be the first');", 5000);
await sleep(5000);
alert('this should be the second one');
}
demo();
Just put it inside the callback:
setTimeout(function() {
alert('this alert is timedout and should be the first');
alert('this should be the second one');
}, 5000);
No, as there is no delay function in Javascript, there is no way to do this other than busy waiting (which would lock up the browser).
ES6 (busy waiting)
const delay = (ms) => {
const startPoint = new Date().getTime()
while (new Date().getTime() - startPoint <= ms) {/* wait */}
}
usage:
delay(1000)
You can create a promise and await for its fulfillment
const timeOut = (secs) => new Promise((res) => setTimeout(res, secs * 1000));
await timeOut(1000)
Here's a good way to make synchronous delay in your code:
async function yourFunction() {
//your code
await delay(n);
//your code
}
function delay(n) {
n = n || 2000;
return new Promise(done => {
setTimeout(() => {
done();
}, n);
});
}
Found it here Right way of delaying execution synchronously in JavaScript without using Loops or Timeouts!
setTimeout(function() {
yourCode(); // alert('this alert is timedout and should be the first');
otherCode(); // alert("this should be the second one");
}, 5000);
I think you have to make a promise and then use a .then() so that you can chain your code together. you should look at this article https://developers.google.com/web/fundamentals/primers/promises
You could attempt to replace window.setTimeout with your own function, like so
window.setTimeout = function(func, timeout) {
func();
}
Which may or may not work properly at all. Besides this, your only option would be to change the original code (which you said you couldn't do)
Bear in mind, changing native functions like this is not exactly a very optimal approach.