如何理解并解决调用顺序与打印顺序相反的async/await练习题?
Let's break this down step by step so you can make sense of the problem, fix your errors, and meet the exercise requirements.
First: What Do These Functions Actually Do?
Let's start with the basics to clear up confusion about the print and op functions:
- The
printfunction is a standard Node.js-style callback: it takes an error (if any) and content, then logs the content (or the error if something went wrong). opA,opB, andopCare asynchronous functions that take a callback. After a set timeout, they trigger that callback with no error and their respective letter (A/B/C).
Why Your Original Code Threw an Error
Your code await print(opA()); has two critical issues:
- You didn't pass a callback to
opA:opAexpects acbparameter, but you called it asopA()with no arguments. That means whenopAtries to runcb(null, 'A'),cbisundefined—hence theTypeError: cb is not a function. printdoesn't return a Promise:awaitonly works with Promise objects. Sinceprintjust logs output and returnsundefined, usingawaithere does nothing useful.
The Exercise Isn't a Typo—Here's What It's Asking
The key trick here is separating function call order from asynchronous completion order:
- Requirement 1: Call
opAfirst, thenopB, thenopC. - Requirement 2: Print output in the order
C → B → A.
Because each op has a different timeout (opA = 500ms, opB = 250ms, opC = 125ms), if you call them in order but let them run asynchronously, the shortest timeout finishes first. That gives us exactly the output order we want.
Solution 1: Using Callbacks (Simple, Direct)
Just call the functions in the required order, passing print as the callback to each:
opA(print); opB(print); opC(print);
When you run this, you'll see C log first (125ms later), then B (250ms later), then A (500ms later)—perfectly matching the output requirement, while maintaining the correct call order.
Solution 2: Using Async/Await (For Your Practice)
Since you're practicing async/await, we need to convert the callback-style op functions to return Promises first. We can make a simple promisify helper:
// Convert callback-based function to Promise-based const promisify = (fn) => { return () => new Promise((resolve, reject) => { fn((err, data) => { if (err) reject(err); else resolve(data); }); }); }; // Create Promise versions of our op functions const opAPromise = promisify(opA); const opBPromise = promisify(opB); const opCPromise = promisify(opC);
Now, we need to start all asynchronous operations first (to maintain the opA → opB → opC call order), then wait for them to resolve in reverse order to get the C → B → A output:
(async function() { // Start all async operations in the required order const promiseA = opAPromise(); const promiseB = opBPromise(); const promiseC = opCPromise(); // Wait for and print results in reverse order print(null, await promiseC); print(null, await promiseB); print(null, await promiseA); })();
This works because we first kick off all three async tasks (calling opA first, then opB, then opC), then wait for the fastest one (promiseC) to finish and print, then the next, then the slowest. The output will be C → B → A as required.
内容的提问来源于stack exchange,提问作者Sandra Schlichting

