Callbacks, Promises and Futures
Choose how a report result reaches its caller
A report-loading operation needs to deliver either the student’s marks or a failure. Calling code should know how to receive that result without guessing whether it already exists.
A callback is a supplied function. A promise represents one eventual fulfilled value or rejection. A future is a related eventual-result abstraction whose precise operations depend on its language or library.
Compare contracts
Distinguish a callback role from an eventual-result object.
Chain results
Return values needed by the next promise handler.
Handle failure
Explain rejection propagation and recovery.
A chain passes returned results to the next stage
Eventual input
Obtain the marks array.
[40, 35]Transformation
Return the total from then.
75Next handler
Receive the returned total.
Display 75
A promise is a result contract, not a callback count
JavaScript promises begin pending unless already settled. Settlement chooses fulfillment or rejection once. then returns a new promise that follows the callback’s returned value, returned promise or thrown error.
A callback may be called once, never or repeatedly according to its API. For example, a button handler can run for many clicks. An error-first Node.js callback convention uses an error argument and result argument, but not every callback API follows that convention.
Before starting, review callback timing. These examples use JavaScript; other languages can use different syntax and rules.
Return a total through a promise chain
The first handler receives marks and returns 75. The next handler receives that returned number and prints it. The synchronous Waiting message prints before either handler.
No network request occurs: Promise.resolve supplies local marks so we can verify the chain independently of a service.
JavaScript · local teaching example
Promise.resolve([40, 35])
.then(marks => marks[0] + marks[1])
.then(total => console.log(total));
console.log("Waiting");Expected output
Waiting
75A thrown validation error becomes a rejection
The handler rejects invalid marks by throwing. The following success handler is skipped, and catch receives the error. Returning from catch would recover the chain with that returned value.
This error belongs to the promise chain. A try/catch wrapped only around registering the handler would not catch a later thrown error inside it.
JavaScript · local teaching example
Promise.resolve(-1)
.then(mark => {
if (mark < 0) throw new Error("Invalid mark");
return mark;
})
.then(mark => console.log("Saved " + mark))
.catch(error => console.log(error.message));Expected output
Invalid markApply the rule to a small change
Return an uppercase student name from one handler and prefix it in the next handler.
Worked answer
The first handler returns MAYA. The second receives that string and displays Student: MAYA. Omitting the first return would pass undefined instead.
JavaScript · local teaching example
Promise.resolve("Maya")
.then(name => name.toUpperCase())
.then(name => console.log("Student: " + name));Expected output
Student: MAYARecognize mistakes and limits
Return asynchronous work from a handler when later steps must wait for it. Starting a promise inside then without returning it breaks the intended chain and can leave failure unhandled.
A promise is not an automatic cancellation mechanism, a separate thread or proof of success. Cancellation depends on the underlying operation and its API.
Future is not a universal interchangeable name with identical methods. Python concurrent.futures.Future, for example, exposes result and exception behavior that differs from JavaScript then. Learn the concrete API rather than copying syntax between languages.
For the language or tool rules used here, see JavaScript promise chaining and timing.
Check the core idea
Apply the idea to a new situation
JavaScript · code for this question
Promise.resolve(-1)
.then(mark => {
if (mark < 0) throw new Error("Invalid mark");
return mark;
})
.then(mark => console.log("Saved " + mark))
.catch(error => console.log(error.message));Make the completion and failure contract explicit
Callbacks supply callable behavior; promises represent a one-time eventual outcome and support chaining. Return the next result or operation and handle rejection in the chain that owns it.
Connect this idea with awaiting promise results and synchronous and awaited failures.
Reaching the recap and completing the quizzes are separate milestones.