The term promise was proposed in 1976 by Daniel P. Friedman and David Wise, and Peter Hibbard called it eventual.
A somewhat similar concept future was introduced in 1977 in a paper by Henry Baker and Carl Hewitt.
The term promise was coined by arbara Liskov and Liuba Shrira in 1988
The future and/or promise constructs were first implemented in programming languages such as MultiLisp and Act 1. ca. 1989.
Deferred
which is also a derivative implementation of the CommonJS Promises/A proposal.But $.Deferred
sucked
pipe
method to chain operations together... so Domenic Denicola got angry and wrote
...and he made http://promisesaplus.com/
Asynchronous JavaScript, or JavaScript that uses callbacks, is hard to get right intuitively.
fs.readFile('test.txt', function (err, data) {
if (err) return console.error(err);
db.insert({
fileName: 'test.txt',
fileContent: data
}, function (err, result) {
if (err) return console.error(err);
smtp.send({
to: 'test@test.com',
body: 'This is a test.'
}, function (err) {
if (err) return console.error(err);
console.log("Success email sent.");
});
});
});
See all the instances offunction
and})
? Eek! This is affectionately known as callback hell
fs.readFile('test.txt', function onReadFile(err, data) {
db.insert(..., function onInsert(err, result) {
smtp.send(..., function onSend(err) { ... });
});
});
As you can see naming functions is super easy and does some nice things to your code:
fs.readFile('test.txt', onReadFile);
function onReadFile(err, data) {
if (err) return console.error(err);
db.insert({
fileName: 'test.txt',
fileContent: data
}, onInsert);
}
function onInsert(err, result) {
if (err) return console.error(err);
smtp.send({
to: 'test@test.com',
body: 'This is a test.'
}, onSend);
}
function onSend(err) {
if (err) return console.error(err);
console.log("Success email sent.");
}
A Promise represents the pending result of a computation that may not have completed yet.
Once in the fulfilled or rejected state, a Promise become immutable--neither its state nor its result (or error/reason) can be modified.
A Promise starts in an unresolved or pending state. For example, the Promise for a computation that hasn't yet completed is in the pending state. At some point the computation will either complete successfully, thus producing a result, or fail, either generating some sort of error or reason why it could not complete.
If the computation completes successfully, its Promise will transition to the fulfilled state, and all consumers will be notified of the actual result. In other words, their callback
will be invoked and passed the result.
If the computation fails, its Promise will transition to the rejected state, and all consumers will be notified of the error or reason for the failure. In other words, their errorback
will be invoked and passed the result.
fs.readFile('test.txt').then(function (data) {
return db.insert({
fileName: 'test.txt',
fileContent: data
});
}).then(function (result) {
return smtp.send({
to: 'test@test.com',
body: 'This is a test.'
});
}).then(function () {
console.log("Success email sent.");
}, console.error);
console.error
fs.readFile('test.txt').then(function (data) {
return db.insert({
fileName: 'test.txt',
fileContent: data
});
}).then(function (result) {
return smtp.send({
to: 'test@test.com',
body: 'This is a test.'
});
}).then(function () {
console.log("Success email sent.");
}).then(function () {
return ajax.request({ url: "/some/path" });
}).then(console.info, console.error, console.debug);
console.info
, console.error
, console.debug
A producer is responsible for providing the result of the computation, and typically, but not always, will be the same component that created the Deferred.
As the name implies, a consumer observes the result of the computation.
From the outside consumers can observe the outcome the computation, but not interfere with the computation itself.
From the inside the the producer can resolve the promise with the outcome from the computation.
*Your mileage may vary depending on implementation
.join
and .all
.any
and .some
.map
and .reduce
.sequence
and .pipeline
.parallel