Muirik
Muirik

Reputation: 6289

Understanding Where to Place `await` Keyword

Just to be sure I understand how async/await works, I'd like to confirm something. Let me first create a couple of functions:

let resolveAfter2Seconds = () => {
  console.log("starting slow promise");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve(20);
      console.log("slow promise is done");
    }, 2000);
  });
};

let resolveAfter1Second = () => {
  console.log("starting fast promise");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve(10);
      console.log("fast promise is done");
    }, 1000);
  });
};

Now, take these two blocks of code for example:

let concurrentStart = async () => {
  console.log('==CONCURRENT START with await==');
  const slow = resolveAfter2Seconds();
  const fast = resolveAfter1Second();

  console.log(await slow);
  console.log(await fast);
}

Now, is it the case that the above is functionally equivalent to this:

let concurrentStart = async () => {
  console.log('==CONCURRENT START with await==');
  const slow = await resolveAfter2Seconds();
  const fast = await resolveAfter1Second();

  console.log(slow);
  console.log(fast);
}

In other words, I can either put the await keyword right before the function call await resolveAfter25Seconds(), or... I can put the await in the console log that triggers the firing of that function - console.log(await slow);.

Will the result be the same, in the sense that async/await will work in the same way in both cases -- in which case you could accomplish the same thing with either approach?

Upvotes: 4

Views: 239

Answers (1)

dtanabe
dtanabe

Reputation: 1661

They behave differently; your first example runs for two seconds and your second example runs for three seconds.

In the first case, slow and fast are allowed to start in parallel; in the second case, you force the first promise to resolve before even starting the second one.

A real-world use-case of kicking off many promises without awaiting them is if you wanted to fetch multiple URLs in parallel.

// assuming getUrlContents() returns a Promise
let promises = [
    getUrlContents('http://url1.com/'),
    getUrlContents('http://url2.com/'),
    getUrlContents('http://url3.com/')
];

// all URLs are currently fetching

// now we wait for all of them; doesn't particularly matter what order
// they resolve
let results = [
    await promises[0],
    await promises[1],
    await promises[2]
];

Another variation of this would run much more slowly (and usually not what you want unless you really DID need the contents of one before being able to proceed with the next one):

let a = await getUrlContents('http://url1.com/')
let b = await getUrlContents('http://url2.com/')
let c = await getUrlContents('http://url3.com/')
let results = [ a, b, c ];

The download for b wouldn't start until after a completed, and so on.

Upvotes: 4

Related Questions