In order to answer the question of "What is a Promise?", we should ask the question "Why is a Promise?". What is the problem that promises are supposed to solve? Although Marco Alka's answer is close, but that solution can easily be solved by a callback. In fact, Node.js uses a callback for its file operations (although that will be soon changing that to Promises). This how we could have a baker work using a callback and handle the errors:
baker.bake('cake', function (err, cake) {
if (err) {
console.error(err);
return;
}
peasant.eat(cake);
});
I was able to handle the error. So what does a promise give us extra over a callback? Well, lets say that all of the peasants decided to revolt, because that is all the ungrateful bunch ever think about. So when I call "peasant.eat(cake)", they just throw a fit. How am I supposed to handle that? Well, with promises, these sort of errors can be handled.
baker.bake('cake')
.then(peasant.eat) //Let's just pretend that 'this' remains the same
.catch(console.error)
So now, whether this failed because the baker died or the peasants are revolting, I get notified that someone is not eating their cake.
Well, let's think about this. If the baker is not doing his work, he is easily replaced. I don't care if he is sick, injured, or dead. For all I know, he could be joining those peasants. So if we want to replace him, it could be as simple as:
baker.bake('cake')
.then(peasant.eat, () => executioner.fireAndReplace(baker)) // I would put quotes around "fire", but JavaScript syntax doesn't allow me
.catch(console.error)
So now, if a error showed up, I can replace that filthy baker. Of course, more work will have to be done so that the bakers family doesn't start questioning where he is, also reimbursement of the peasant who didn't get his cake, but you can see that this is beginning to take shape.
So as an overview. Promises allow for better handling of chaining operations. Errors in the chain get propagated to the nearby error handler, whether it be with ".then(success, error)" or ".catch(error)". It also standardizes error handling, as my error parameter could have been the first argument or the last.