Recent chats
ASKGEEZ Q&A GUIDETechnology & devices

How can I run dependent asynchronous steps in the right order?

Quick answer

Use await on each asynchronous operation whose result the next step needs, then pass that result along. For example, await loading an order, use its customer ID to load the customer, and then create a receipt from both. If two operations do not depend on each other, start them together with Promise.all() instead of waiting for one before starting the other. [S1]

LET’S WORK THROUGH IT

The question, the details, the next step.

Question

I have several asynchronous steps, and the later ones need results from earlier ones. How do I make sure they run in the right order?

Geez

Write the dependency in the code: await the first operation, save its result, and use that result in the next operation. Repeat for each dependency. In this illustrative example, assume the named functions return promises:

async function buildReceipt() {
  const order = await loadOrder();
  const customer = await loadCustomer(order.customerId);
  const receipt = await createReceipt(order, customer);
  return receipt;
}

The second step needs order.customerId, so it comes after loadOrder() finishes. The third needs both order and customer, so it comes after both values have been obtained. Promises can be composed this way: await an operation, then pass its result to the next dependent operation. [S1] The function names and returned data here are placeholders, not assumptions about a particular service.

Follow-up question

Why not start all three operations at once and await them together?

Geez

That only fits operations that can begin without results from one another. In this example, loadCustomer cannot be called with the order’s customer ID until the order has been loaded, and createReceipt needs the order and customer. Starting those steps before their inputs exist would not express the dependency.

Check each operation’s inputs: if a required value is produced by an earlier step, wait for that step and pass the value along. If there is no such dependency, those operations may be started together. The dependency order comes from the data each step needs, not merely from the order you happen to list the functions.

Follow-up question

What does the code look like when two steps are independent, but both are needed before I continue?

Geez

Start both operations together with Promise.all(), then use the results after it resolves. For example, assuming these placeholder functions return promises and neither needs the other’s result:

async function makeDashboard() {
  const [sales, inventory] = await Promise.all([
    loadSales(),
    loadInventory()
  ]);

  return buildDashboard(sales, inventory);
}

Here, loadSales() and loadInventory() are independent inputs to the final step. Promise.all() lets the independent operations run together rather than imposing an unnecessary serial wait; after both results are available, the code continues to buildDashboard. [S1] This example illustrates ordering only; it does not establish how any particular function handles errors or what data it returns.

Follow-up question

How can I check that I have ordered a longer workflow correctly?

Geez

Write down each step’s required inputs and where they come from. Then place each step after the operation that produces its inputs. Keep independent steps together only when neither needs the other’s result. For the receipt example, the dependency chain is: load order → load customer using the order’s customer ID → create receipt from order and customer.

A reusable pattern is:

async function runWorkflow() {
  const firstResult = await firstStep();
  const secondResult = await secondStep(firstResult);
  const thirdResult = await thirdStep(secondResult);
  return thirdResult;
}

Treat the names as placeholders and adjust the inputs to match your actual workflow. This pattern shows sequencing; it does not by itself define error handling, retries, or the behavior of the operations you call.

A practical checklist

  • List each asynchronous operation and the values it requires.

  • Identify which earlier operation produces each required value.

  • Use await before a dependent step, and pass the result into that step.

  • Use Promise.all() for operations that are independent but whose results are both needed later. [S1]

  • Check that each step’s result is used only after that operation has been awaited.

A few more useful answers

Does `await` make every asynchronous operation sequential?

In a sequence where each operation is awaited before the next begins, it makes that code wait at each step. For independent operations, starting them together with Promise.all() can avoid unnecessary serial waiting. [S1]

Can I use `Promise.all()` when the second operation needs the first result?

Not as written if the second operation needs a value that does not exist until the first finishes. Await the first operation, pass its result to the second, and only group operations that are independent.

Does this sequence handle failures or retries?

No. The examples explain ordering and passing results, not how failures or retries should be handled. Those behaviors depend on the operations and the requirements of your application.

Sources

References used for this guide.

  1. [S1] Using promises — JavaScript | MDN
    developer.mozilla.org · Checked

YOUR QUESTION. YOUR DETAILS.

Let’s work through your situation.

Get a tailored answer or help with your next task. Starts at $1, with a quote before you pay.

Ask your own question
← Back to Geez at Work