I have lot of confusion in promise. It's a synchronous or asynchronous ?
return new Promise (function(resolved,reject){
//sync or async?
});
The function you pass into the Promise constructor runs synchronously, but anything that depends on its resolution will be called asynchronously. Even if the promise resolves immediately, any handlers will execute asynchronously (similar to when you setTimeout(fn, 0)) - the main thread runs to the end first.
This is true no matter your Javascript environment - no matter whether you're in Node or a browser.
console.log('start');
const myProm = new Promise(function(resolve, reject) {
console.log('running');
resolve();
});
myProm.then(() => console.log('resolved'));
console.log('end of main block');
Promises aren't exactly synchronous or asynchronous in and of themselves. When you create a promise the callback you pass to it is immediately executed and no other code can run until that function yields. Consider the following example:
new Promise(function(resolve, reject) {
console.log('foo');
})
console.log('bar');
The code outside the promise has to wait for the code inside the promise (which is synchronous) to complete before it can begin execution.
That said, promises are a common way of dealing with asynchronous code. The most common use case for a promise is to represent some value that's being generated or fetched in an asynchronous fashion. Logic that depends on that value can asynchronously wait until the value is available by registering a callback with .then() or related Promise methods.
This code makes it clearer:
console.log("0");
new Promise((resolve, reject) => {
console.log("1");
resolve();
}).then(() => {
console.log("2");
});
console.log("3");
The code prints: 0 1 3 2
So, then runs asynchronously while the main call back function runs synchronously.
I don't find other answers are accurate.
new Promise (executor_function)
executor_function here will run immediately as part of Promise initialization --- this means Promise init will be executed synchronously, but does not mean code inside executor_function will necessarily run synchronously, instead, code inside executor_function can also be run asynchronously, for example:
new Promise ((resolve, reject) => {
setTimeout(resolve, 1000); // wait 1s
})
When you create a promise and pass a call back to it
that callback is gonna executed immediately (sync)
const promise= new Promise(function(resolve, reject) {
//doing some logic it gonna be executed synchronously
console.log("result");
})
console.log("global log")
But when you resolve it by .then() method it will act in asynchronous way
so for example :
const promise = new Promise(function(resolve, reject) {
//doing some logic it gonna be executed synchronously
resolve("fullfiled")
})
promise.then(v => {
console.log(v)
})
console.log("global log")
Promises are like normal classes in Javascript. Assume you are creating your own Promise implementation, your promise class would roughly look like this. Notice in your constructor you are expecting a method to be passed that you call immediately passing resolve and reject as parameters.
class Promise {
constructor(method) {
method(resolve, reject)
}
resolve() { ... }
reject() { ... }
then() { ... }
}
So when you do new Promise(), you are just creating a new object. Your Promise constructor will run, and it will call the method immediately. So that is why the code inside your promise gets executed synchronously.
return new Promise (function(resolved,reject){
//sync or async?
});
If inside your function you were calling another function that was async in nature, then that another function would get executed asynchronously, otherwise, everything else gets executed synchronously.
If you had chains in promise using then, then it only gets called after your first promise has called resolve().
return new Promise (function(resolve,reject){
const a = 5*5; // sync operation.
db.save(a, function callback() { // async operation.
resolve() // tells promise to execute `then` block.
});
});
const promise = new Promise(function(resolve, reject) {
//doing some logic it gonna be executed synchronously
console.log("check")
resolve("fullfiled")
})
promise.then(v => {
console.log(v)
})
console.log("global log")
Related
Suppose I have the following Promise:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
const result = doSomeWork();
setTimeout(() => {
resolve(result);
}), 100);
});
}
At which point in time is doSomeWork() called? Is it immediately after or as the Promise is constructed? If not, is there something additional I need to do explicitly to make sure the body of the Promise is run?
Immediately, yes, by specification.
From the MDN:
The executor function is executed immediately by the Promise implementation, passing resolve and reject functions (the executor is called before the Promise constructor even returns the created object)
This is defined in the ECMAScript specification (of course, it's harder to read...) here (Step 9 as of this edit, showing that the executor is called synchronously):
Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
(my emphasis)
This guarantee may be important, for example when you're preparing several promises you then pass to all or race, or when your executors have synchronous side effects.
You can see from below the body is executed immediately just by putting synchronous code in the body rather than asynchronous:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous();
console.log("b");
The result shows the promise body is executed immediately (before 'b' is printed).
The result of the Promise is retained, to be released to a 'then' call for example:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous().then(function(pr) {
console.log("c:" + pr);
});
console.log("b");
Result:
a
b
c:promise result
Same deal with asynchronous code in the body except the indeterminate delay before the promise is fulfilled and 'then' can be called (point c). So a and b would be printed as soon as doSomethingAsynchronous() returns but c appears only when the promise is fulfilled ('resolve' is called).
What looks odd on the surface once the call to then is added, is that b is printed before c even when everything is synchronous.
Surely a would print, then c and finally b?
The reason why a, b and c are printed in that order is because no matter whether code in the body is async or sync, the then method is always called asynchronously by the Promise.
In my mind, I imagine the then method being invoked by something like setTimeout(()=>{then(pr)},0) in the Promise once resolve is called. I.e. the current execution path must complete before the function passed to then will be executed.
Not obvious from the Promise specification why it does this?
My guess is it ensures consistent behavior regarding when then is called (always after current execution thread finishes) which is presumably to allow multiple Promises to be stacked/chained together before kicking off all the then calls in succession.
Yes, when you construct a Promise the first parameter gets executed immediately.
In general, you wouldn't really use a promise in the way you did, as with your current implementation, it would still be synchronous.
You would rather implement it with a timeout, or call the resolve function as part of an ajax callback
function doSomethingAsynchronous() {
return new Promise((resolve) => {
setTimeout(function() {
const result = doSomeWork();
resolve(result);
}, 0);
});
}
The setTimeout method would then call the function at the next possible moment the event queue is free
From the EcmaScript specification
The executor function is executed immediately by the Promise
implementation, passing resolve and reject functions (the executor is
called before the Promise constructor even returns the created object)
Consider the following code:
let asyncTaskCompleted = true
const executorFunction = (resolve, reject) => {
console.log("This line will be printed as soon as we declare the promise");
if (asyncTaskCompleted) {
resolve("Pass resolved Value here");
} else {
reject("Pass reject reason here");
}
}
const myPromise = new Promise(executorFunction)
When we execute the above code, executorFunction will be called automatically as soon as we declare the Promise, without us having to explicitly invoke it.
Suppose I have the following Promise:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
const result = doSomeWork();
setTimeout(() => {
resolve(result);
}), 100);
});
}
At which point in time is doSomeWork() called? Is it immediately after or as the Promise is constructed? If not, is there something additional I need to do explicitly to make sure the body of the Promise is run?
Immediately, yes, by specification.
From the MDN:
The executor function is executed immediately by the Promise implementation, passing resolve and reject functions (the executor is called before the Promise constructor even returns the created object)
This is defined in the ECMAScript specification (of course, it's harder to read...) here (Step 9 as of this edit, showing that the executor is called synchronously):
Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
(my emphasis)
This guarantee may be important, for example when you're preparing several promises you then pass to all or race, or when your executors have synchronous side effects.
You can see from below the body is executed immediately just by putting synchronous code in the body rather than asynchronous:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous();
console.log("b");
The result shows the promise body is executed immediately (before 'b' is printed).
The result of the Promise is retained, to be released to a 'then' call for example:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous().then(function(pr) {
console.log("c:" + pr);
});
console.log("b");
Result:
a
b
c:promise result
Same deal with asynchronous code in the body except the indeterminate delay before the promise is fulfilled and 'then' can be called (point c). So a and b would be printed as soon as doSomethingAsynchronous() returns but c appears only when the promise is fulfilled ('resolve' is called).
What looks odd on the surface once the call to then is added, is that b is printed before c even when everything is synchronous.
Surely a would print, then c and finally b?
The reason why a, b and c are printed in that order is because no matter whether code in the body is async or sync, the then method is always called asynchronously by the Promise.
In my mind, I imagine the then method being invoked by something like setTimeout(()=>{then(pr)},0) in the Promise once resolve is called. I.e. the current execution path must complete before the function passed to then will be executed.
Not obvious from the Promise specification why it does this?
My guess is it ensures consistent behavior regarding when then is called (always after current execution thread finishes) which is presumably to allow multiple Promises to be stacked/chained together before kicking off all the then calls in succession.
Yes, when you construct a Promise the first parameter gets executed immediately.
In general, you wouldn't really use a promise in the way you did, as with your current implementation, it would still be synchronous.
You would rather implement it with a timeout, or call the resolve function as part of an ajax callback
function doSomethingAsynchronous() {
return new Promise((resolve) => {
setTimeout(function() {
const result = doSomeWork();
resolve(result);
}, 0);
});
}
The setTimeout method would then call the function at the next possible moment the event queue is free
From the EcmaScript specification
The executor function is executed immediately by the Promise
implementation, passing resolve and reject functions (the executor is
called before the Promise constructor even returns the created object)
Consider the following code:
let asyncTaskCompleted = true
const executorFunction = (resolve, reject) => {
console.log("This line will be printed as soon as we declare the promise");
if (asyncTaskCompleted) {
resolve("Pass resolved Value here");
} else {
reject("Pass reject reason here");
}
}
const myPromise = new Promise(executorFunction)
When we execute the above code, executorFunction will be called automatically as soon as we declare the Promise, without us having to explicitly invoke it.
I've tried to understand Promise
from google source, and haven't found how it execute code asynchronously.
My understanding of asynchronous function is that code below it can be resolved at a time before it.
For example:
setTimeout(()=>{console.log("in")}, 5000);
console.log("out");
// output:
// out
// in
The second line fufilled before the first line , so I think setTimeout is an asynchronous tech. But see this code of Promise:
let p = new Promise((resolve, reject)=>{console.log('in'); resolve(1);});
console.log("out");
//in
//out
This code block is actually excuted line by line, if console.log('in'); is a time-consuming operation, the second line will be blocked until it's resolved.
We usually use Promise like this:
(new Promise(function1)).then(function2).then(function3)
Does this mean: Promise is just used to promise that function2 is executed after function1, it's not a tech to realize asynchronous ,but a method to realize synchronous (function1, function2, function3 are executed sequently).
A promise is just a way to describe a value that does not exist yet, but will arrive later. You can attach .then handlers to it, to get notified if that happens.
Does this mean: Promise is just used to promise that function2 is executed after function1?
Yes exactly, even if function1 returns it's value asynchronously (through a Promise), function2 will run only if that value is present.
it's not a tech to realize 'asynchronous' but a method to realize 'synchronous' [execution] ?
Not really. It makes little sense to wrap a value that already exists into a promise. It makes sense to wrap a callback that will call back "asynchronously" into a promise. That said, the Promise itself does not indicate wether the value it resolves to was retrieved in a synchronous or asynchronous maner.
function retrieveStuffAsynchronously() {
// direclty returns a Promise, which will then resolve with the retrieved value somewhen:
return new Promise((resolve, reject) => {
// directly executes this, the async action gets started below:
setTimeout(() => { // the first async code, this gets executed somewhen
resolve("the value"); // resolves asynchronously
}, 1000);
});
}
console.log(retrieveStuffAsynchronously()); // does return a promise immeadiately, however that promise is still pending
retrieveStuffAsynchronously().then(console.log);
Sidenote: However, Promises are guaranteed to resolve asynchronously:
const promise = new Promise((resolve, reject)=>{
console.log('one');
resolve('three');
});
promise.then(console.log); // guaranteed to be called asynchronously (not now)
console.log("two");
I create two promises, but I do not run the then method on those promises. Yet once the promise objects go out of scope, the promise code runs as if .then was called.
How is a Promise settled without a call to the .then method?
I am asking because I would like to load an array with Promise objects and then run the promises in sequence.
function promises_createThenRun() {
const p1 = createPromise1();
const p2 = createPromise2();
console.log('before hello');
alert('hello');
console.log('after hello');
// the two promises run at this point. What makes them run?
}
function createPromise1() {
let p1 = new Promise((resolve, reject) => {
window.setTimeout(() => {
console.log('timer 1');
resolve();
}, 2000);
});
return p1;
}
function createPromise2() {
let p2 = new Promise((resolve, reject) => {
window.setTimeout(() => {
console.log('timer 2');
resolve();
}, 1000);
});
return p2;
}
The code inside the Promise constructor runs when the promise is created and it runs synchronously which surprises some people. So even without then() everything still runs.
new Promise(resolve => console.log("running"))
Code in the callback for the setTimeout however, doesn't run until it's called, but it too will run even without the then()
new Promise(resolve => {
console.log("promise created")
setTimeout(() => console.log("this runs later"), 1000)
})
When calling .then you just set up a "callback" which says what should happen after the promise is done. So the promise will be called, with or without declaring such callback.
Imagine the promise that calls a AJAX request. Calling .then and passing a function to it will make it run when the ajax call was finished (successfully or not as in timeout or other errors). But not calling .then will not stop the request to be run. You will simply not react to the results of the request.
I thought, that "Promises won't run" if you don't call then/catch/finally on them, too. But if you consider, that these methods return new Promises, and according to your logic, you need to call then/catch/finally on these returned Promises in order to "run" them, you'll be stuck in an infinite loop)))
Suppose I have the following Promise:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
const result = doSomeWork();
setTimeout(() => {
resolve(result);
}), 100);
});
}
At which point in time is doSomeWork() called? Is it immediately after or as the Promise is constructed? If not, is there something additional I need to do explicitly to make sure the body of the Promise is run?
Immediately, yes, by specification.
From the MDN:
The executor function is executed immediately by the Promise implementation, passing resolve and reject functions (the executor is called before the Promise constructor even returns the created object)
This is defined in the ECMAScript specification (of course, it's harder to read...) here (Step 9 as of this edit, showing that the executor is called synchronously):
Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
(my emphasis)
This guarantee may be important, for example when you're preparing several promises you then pass to all or race, or when your executors have synchronous side effects.
You can see from below the body is executed immediately just by putting synchronous code in the body rather than asynchronous:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous();
console.log("b");
The result shows the promise body is executed immediately (before 'b' is printed).
The result of the Promise is retained, to be released to a 'then' call for example:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous().then(function(pr) {
console.log("c:" + pr);
});
console.log("b");
Result:
a
b
c:promise result
Same deal with asynchronous code in the body except the indeterminate delay before the promise is fulfilled and 'then' can be called (point c). So a and b would be printed as soon as doSomethingAsynchronous() returns but c appears only when the promise is fulfilled ('resolve' is called).
What looks odd on the surface once the call to then is added, is that b is printed before c even when everything is synchronous.
Surely a would print, then c and finally b?
The reason why a, b and c are printed in that order is because no matter whether code in the body is async or sync, the then method is always called asynchronously by the Promise.
In my mind, I imagine the then method being invoked by something like setTimeout(()=>{then(pr)},0) in the Promise once resolve is called. I.e. the current execution path must complete before the function passed to then will be executed.
Not obvious from the Promise specification why it does this?
My guess is it ensures consistent behavior regarding when then is called (always after current execution thread finishes) which is presumably to allow multiple Promises to be stacked/chained together before kicking off all the then calls in succession.
Yes, when you construct a Promise the first parameter gets executed immediately.
In general, you wouldn't really use a promise in the way you did, as with your current implementation, it would still be synchronous.
You would rather implement it with a timeout, or call the resolve function as part of an ajax callback
function doSomethingAsynchronous() {
return new Promise((resolve) => {
setTimeout(function() {
const result = doSomeWork();
resolve(result);
}, 0);
});
}
The setTimeout method would then call the function at the next possible moment the event queue is free
From the EcmaScript specification
The executor function is executed immediately by the Promise
implementation, passing resolve and reject functions (the executor is
called before the Promise constructor even returns the created object)
Consider the following code:
let asyncTaskCompleted = true
const executorFunction = (resolve, reject) => {
console.log("This line will be printed as soon as we declare the promise");
if (asyncTaskCompleted) {
resolve("Pass resolved Value here");
} else {
reject("Pass reject reason here");
}
}
const myPromise = new Promise(executorFunction)
When we execute the above code, executorFunction will be called automatically as soon as we declare the Promise, without us having to explicitly invoke it.