A promise is a
(...) value which may be available now, or in the future, or never (Source: MDN)
So lets say I have an app which wants to work with pictures. The pictures are loaded e.g. after an algorithm works with it in the background (or some other sort of delay). Now I want to check, if the pictures are available in the future, by using a promise, not a callback.
To check, if an image is available, I could use the following code:
function loadImage(url) {
return new Promise((resolve, reject) => {
let image = new Image()
image.onload = function() {
resolve(image)
}
image.onerror = function() {
let message =
'Could not load image at ' + url
reject(new Error(msg))
}
image.src = url
})
}
The promise, which belongs to this would look something like this:
Promise.all([
loadImage('images/pic1.jpg'),
loadImage('images/pic2.jpg')
]).then((images) => {
images.forEach(img => addImg(img.src))
}).catch((error) => {
// handle error
})
This will not help my at all, because the promise will look up if the pictures are available in the present, not in the future. The pictures will be there in a second, still the promise will return an error.
What do I not get about promises here? For me it looks like the entire future aspect of checking, if the pics are available depends on loadImage(url)
not on the actual promise itself.
PS: Example inspired by funfunfunction
How would the promise know when it is resolved?
To my understanding it does not "listen" to the other code around it, let alone a framework which might run in the background. I would assume in this example it would turn out like this: promise checks if pictures are available -> they are still worked with in the background -> promise resolves and throws error -> algorithm is finished with pictures -> pictures are available ?
What is the point of promises in JavaScript?
See: You're Missing the Point of Promises.
Cannot consider all of the nuances relevant to using Promise
alone. Browse the promise
tag to read other users' questions and answers posted by users whom post frequently at promise
tag. Ask questions as to specific cases at comments at those questions and answers, for your own edification.
You get the value of a Promise
using .then()
or .catch()
, not by checking the value of a variable outside of Promise
chain.
Disregard "present" and "future". Focus on implementing code within .then()
and, or .catch()
. All other code referencing an asynchronous value referenced by an identifier will not be reliable.
let id = void 0;
let promise = new Promise(resolve =>
setTimeout(() => {id = 123; resolve(id) }, Math.random() * 2000)
);
// this is not accurate
console.log(`id: ${id}`); // what is `id` here?
promise.then(res => console.log(`id: ${res}`));
Note also, function passed to Promise
constructor as executor is called immediately
let id = void 0;
let promise = new Promise(resolve =>
setTimeout(resolve, Math.random() * 2000, id = 123)
);
// is this accurate?
console.log(`id: ${id}`); // what is `id` here?
promise.then(res => console.log(`id: ${res}`));
return
a value from .then()
.
return
a value from .then()
. Use .map()
instead of .forEach()
Promise.resolve(123)
.then(data => console.log(data))
.then(res => console.log(res)) // `undefined`
Promise.resolve(123)
.then(data => { console.log(data); return data})
.then(res => console.log(res)) // `123`
Use .map()
instead of .forEach()
let fn = (id) => new Promise(resolve =>
setTimeout(resolve, Math.random() * 2000, id)
);
Promise.all([1,2,3].map(fn))
.then(data => Promise.all(data.forEach(id => fn(id * 10))))
.then(data => console.log(`data: ${data}`)); // where is `data`
Promise.all([1,2,3].map(fn))
.then(data => Promise.all(data.map(id => fn(id * 10))))
.then(data => console.log(`data: ${data}`)); // `[10, 20, 30]`
A handled rejection or error is converted to a resolved Promise
is not throw
n or rejection returned
let fn = () => new Promise((resolve, reject) =>
setTimeout((id) => {reject(new Error(id)) }, Math.random() * 2000, 123)
)
fn().then(res => console.log(`id: ${res}`))
.catch(err => console.log(`err: ${err}`))
.then(res => console.log(`res: ${res}`)) // `undefined`
fn().then(res => console.log(`res: ${res}`))
.catch(err => { console.log(`err: ${err}`); return err })
// `.then()` is not called, function passed to `.catch()` is called
.then(res => console.log(`res: ${res}`))
.catch(err => console.log(`err: ${err}`)) // `123`