I was searching about callback in JavaScript when I found this question:
How to really learn how to use promises in> (promises) in javascript?
But after all:
- What are promises?
- What are they for?
I was searching about callback in JavaScript when I found this question:
How to really learn how to use promises in> (promises) in javascript?
But after all:
Promises of javascript is an implementation of Futures idea of functional programming.
It has become the standard way to work with asynchronous code in javascript.
A promise object holds the promise that the function that generated it will at some point in the future end and return you an answer. It can be a positive or negative response. The promise can be passed to other functions or returned.
Today there are several implementations of promise for javascript. All end up following this specification .
The advantages of using promises rather than callbacks is that you avoid callback hells and callback cascades that make code hard to read and understand.EDIT: I've put more relevant examples that show the potential of promises when you have multiple levels of callback.
Ex with callback.
function isUserTooYoung(id, callback) {
openDatabase(function(db) {
getCollection(db, 'users', function(col) {
find(col, {'id': id},function(result) {
result.filter(function(user) {
callback(user.age < cutoffAge)
})
})
})
})
}
The nesting level can become much larger than this ... and it gets more and more complicated to understand.
with promises would look like this:
function isUserTooYoung(id) {
return openDatabase(db)
.then(getCollection)
.then(find.bind(null, {'id': id}))
.then(function(user) {
return user.age < cutoffAge;
});
}
Each function does just what it should do and does not have to worry about calling callback or knowing what function it called it is waiting for.
Promise
is an object that represents the result of an asynchronous operation, and this result can be successful (generated by called the resolve
function and triggers the then
method call) or unsuccessful (generated by the reject
function call and triggers the catch
method call). A simple example to illustrate the concept:
// Aqui criamos uma Promesa que será "resolvida" após o disparo do timer
// (1 segundo)
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
$('body').append('Timer executado<br>');
resolve();
}, 1000);
});
// a função anônima passada como parâmetro para ".then" representa a ação que
// será realizada quando nossa promessa for resolvida/cumprida
p.then(function() {
$('body').append('Promise resolvida<br>');
});
$('body').append('Texto qualquer<br><br>');
<script src="https://cdn.jsdelivr.net/es6-promise/3.1.2/es6-promise.min.js"></script><scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
In this example setTimeout
is an asynchronous operation that is transformed into a Promise
and assigned the variable p
. So we have the p
variable that represents the promise of some operation that will eventually occur, and in this case it occurs after the stipulated time in the timer, 1 second / 1000 milliseconds, when append is made of the string "'Timer executado<br>'"
e Promise is terminated through the call of the resolve
function, thereby triggering the then
method that executes the append function of the "Promise resolvida"
string.
As for the utility of Promises, this is in its ability to represent asynchronous flow in a way understandable to the developer. As an example, see the traditional / old way to represent such a stream in javascript:
algumaFnAsync(function() {
outraAsyncFn(function() {
maisUmaAsyncFn(function() {
// código que faz algo após todas
// as operações assíncronas terem completado
});
});
});
You have asynchronous functions that receive an anonymous function as a parameter, and this function will be executed when that asynchronous function finishes its execution. It's not hard to see the problem there, in series of asynchronous codes that need to be executed one after another you end up with several levels of nesting, called callback hell (I did not find a good ref in PT). Promises solve this problem, see how the previous example could be rewritten by using them:
algumaFnAsync().then(function() {
return outraAsyncFn();
}).then(function() {
return maisUmaAsyncFn();
}).then(function() {
// código que faz algo após todas as operações assíncronas terem completado
});
The code is clearer in its intent and the representation is much closer to a synchronous flow where you have "do this, then this, then that". Although they are a nontrivial abstraction promises are a good solution to the problem which is the asynchronous flow representation in code.