async await Flashcards

1
Q

What do the async and await keywords enable?

A

The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Consider the following code. What is the equivalent without using the async keyword?

async function foo() {
return 1;
}

A

function foo() {
return Promise.resolve(1);
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Will an async function without an await expression run synchronously.

A

Yes it will.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

If there is an await expression inside the function body will an async function always complete asynchronously?

A

yes, If there is an await expression inside the function body, the async function will always complete asynchronously.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What is a good way to think about code after each await expression?

A

Code after each await expression can be thought of as existing in a .then callback. In this way a promise chain is progressively constructed with each reentrant step through the function. The return value forms the final link in the chain.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Are async function declarations hoisted?

A

async function declarations are hoisted to the top of their scope and can be called anywhere in their scope.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What are asynchronous actions?

A

Actions that we initiate now, but they finish later.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What is the constructor syntax for a Promise object?

A

let promise = new Promise(function(resolve, reject) {
// executor (the producing code, “singer”)
});

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

What is the function passed to a new promise called?

A

The function passed to new Promise is called the executor.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What should the code in the executor function eventually produce ?

A

The code which should eventually produce the result.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What should the code in the executor function eventually produce ?

A

The code which should eventually produce the result.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What arguments are passed to the executor function. Who provides them?

A

Its arguments resolve and reject are callbacks provided by JavaScript itself. Our code is only inside the executor.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

When the executor obtains the result, it should call one of two callbacks, what are they?

A

When the executor obtains the result, be it soon or late, doesn’t matter, it should call one of these callbacks:

resolve(value) — if the job is finished successfully, pass value as the result.

reject(error) — if an error has occurred, error is the error object.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Summarize the executors behavior and purpose?

A

So to summarize: the executor runs automatically and attempts to perform a job. When it is finished with the attempt, it calls resolve if it was successful or reject if there was an error.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

The promise object returned by the new Promise constructor has what internal properties? Describe them.

A

state — initially “pending”, then changes to either “fulfilled” when resolve is called or “rejected” when reject is called.
result — initially undefined, then changes to value when resolve(value) is called or error when reject(error) is called.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

A promise that is either resolved or rejected is called what? What is the initial state of a promise called?

A

A promise that is either resolved or rejected is called “settled”, as opposed to an initially “pending” promise.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Can the executor call more than one resolve or reject?

A

No there can be only a single result or an error
The executor should call only one resolve or one reject. Any state change is final.

let promise = new Promise(function(resolve, reject) {
resolve(“done”);

reject(new Error(“…”)); // ignored
setTimeout(() => resolve(“…”)); // ignored
});

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

How many arguments do resolve/reject accept?

A

Also, resolve/reject expect only one argument (or none) and will ignore additional arguments.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

In case something goes wrong, the executor should call reject. That can be done with any type of argument (just like resolve). What type of argument is recommended to be used?

A

It is recommended to use Error objects (or objects that inherit from Error).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Can you immediately resolve/reject in an executor?

A

In practice, an executor usually does something asynchronously and calls resolve/reject after some time, but it doesn’t have to. We also can call resolve or reject immediately, like this:

let promise = new Promise(function(resolve, reject) {
// not taking our time to do the job
resolve(123); // immediately give the result: 123
});

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Can you directly access the properties “state” and “result” of a Promise object?

A

No, the properties state and result of the Promise object are internal. We can’t directly access them. We can use the methods .then/.catch/.finally for that.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

The .then( ) method of a Promise accepts two arguments, what are they?

A

The first argument of .then is a function that runs when the promise is resolved and receives the result.

The second argument of .then is a function that runs when the promise is rejected and receives the error.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

In an executor how would you pass an Error as the reject value?

A

reject(new Error(“Whoops!”))

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

Do we need to pass both arguments to .then() ?

A

If we’re interested only in successful completions, then we can provide only one function argument to .then:

let promise = new Promise(resolve => {
setTimeout(() => resolve(“done!”), 1000);
});

promise.then(alert); // shows “done!” after 1 second

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

What is the Promise .catch( ) method the short hand for ?

A

The call .catch(f) is a complete analog of .then(null, f).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

What is the call .finally(f) similar to and why?

A

The call .finally(f) is similar to .then(f, f) in the sense that f runs always, when the promise is settled: be it resolve or reject.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
27
Q

What arguments does a .finally( ) handler accept?

A

A finally handler has no arguments. In finally we don’t know whether the promise is successful or not. That’s all right, as our task is usually to perform “general” finalizing procedures.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
28
Q

Does a Finally handler pass the result or error to the next suitable handler?

A

Yes, A finally handler “passes through” the result or error to the next suitable handler.

new Promise((resolve, reject) => {
setTimeout(() => resolve(“value”), 2000);
})
.finally(() => alert(“Promise ready”)) // triggers first
.then(result => alert(result)); // <– .then shows “value”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
29
Q

Should a finally handler return anything?

A

No, A finally handler also shouldn’t return anything. If it does, the returned value is silently ignored.

The only exception to this rule is when a finally handler throws an error. Then this error goes to the next handler, instead of any previous outcome.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
30
Q

What three things are important to remember about the .finally() method ?

A

A finally handler doesn’t get the outcome of the previous handler (it has no arguments). This outcome is passed through instead, to the next suitable handler.

If a finally handler returns something, it’s ignored.

When finally throws an error, then the execution goes to the nearest error handler.

31
Q

What should the .finally method generally be used for?

A

For generic cleanup procedures.

32
Q

What happens when you attach handlers to already settled promises?

A

If a promise is pending, .then/catch/finally handlers wait for its outcome.

Sometimes, it might be that a promise is already settled when we add a handler to it.

In such case, these handlers just run immediately:

33
Q

What does the following code demonstrate ?

  let promise = new Promise(function (resolve, reject) {
    console.log("executor runs");

    // after 1 second signal that the job is done with the result "done"
    setTimeout(() => {
      resolve("done");
    }, 2000);
  });

  promise.then(
    (result) => console.log(result), 
    (error) => console.log(error) 
  );

  promise.then(
    (result) => console.log("hello"), 
    (error) => console.log(error) 
  );
A

That when you use Promises you can add multiple .then() calls on a Promise object. This means we can add as many handlers as we like. However there is rarely a use case for this and promise chaining is used in most situations.

34
Q

Why can you chain Promise .then() calls like this ?

new Promise(function(resolve, reject) {

setTimeout(() => resolve(1), 1000); // (*)

}).then(function(result) { // (**)

alert(result); // 1
return result * 2;

}).then(function(result) { // (***)

alert(result); // 2
return result * 2;

}).then(function(result) {

alert(result); // 4
return result * 2;

});

A

The whole thing works, because every call to a .then returns a new promise, so that we can call the next .then on it.

35
Q

Is the following promise chaining ?

let promise = new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000);
});

promise.then(function(result) {
alert(result); // 1
return result * 2;
});

promise.then(function(result) {
alert(result); // 1
return result * 2;
});

promise.then(function(result) {
alert(result); // 1
return result * 2;
});

A

A classic newbie error: technically we can also add many .then to a single promise. This is not chaining.
What we did here is just several handlers to one promise. They don’t pass the result to each other; instead they process it independently.

36
Q

What is a thenable and why would you need one?

A

a “thenable” is an arbitrary object that has a method .then. It will be treated the same way as a promise.

The idea is that 3rd-party libraries may implement “promise-compatible” objects of their own. They can have an extended set of methods, but also be compatible with native promises, because they implement .then.

37
Q

How would you create your own thenable object and use it?

A

The short version
You would create an object with a then( ) method. You would then return an instance of the object from a promise. JavaScript checks the object returned for a callable method named then( ), then it calls that method providing native functions resolve, reject as arguments (similar to an executor) and waits until one of them is called. Once either resolve or reject is called it will run the next .then().

The long version with code
JavaScript checks the object returned by the .then handler in line (*): if it has a callable method named then, then it calls that method providing native functions resolve, reject as arguments (similar to an executor) and waits until one of them is called. The last .then will not run until either resolve or reject is called from within the Thenable objects then method.

class Thenable {
constructor(num) {
this.num = num;
}
then(resolve, reject) {
console.log(resolve); // function() { native code }
// resolve with this.num*2 after the 1 second
setTimeout(() => resolve(this.num * 2), 1000); // (**)
}
}

  new Promise((resolve, reject) => resolve(1))
    .then((result) => {
      console.log("result", result);
      return new Thenable(result); // (*)
    })
    .then((result) => {
      console.log(result); // shows 2 after 1000ms
    });
38
Q

What is it good Practice for an asynchronous action to return? Why?

A

As a good practice, an asynchronous action should always return a promise. That makes it possible to plan actions after it; even if we don’t plan to extend the chain now, we may need it later.

39
Q

What does the following code demonstrate?

function loadJson(url) {
return fetch(url)
.then(response => response.json());
}

function loadGithubUser(name) {
return loadJson(https://api.github.com/users/${name});
}

function showAvatar(githubUser) {
return new Promise(function(resolve, reject) {
let img = document.createElement(‘img’);
img.src = githubUser.avatar_url;
img.className = “promise-avatar-example”;
document.body.append(img);

setTimeout(() => {
  img.remove();
  resolve(githubUser);
}, 3000);   }); }

// Use them:
loadJson(‘/article/promise-chaining/user.json’)
.then(user => loadGithubUser(user.name))
.then(showAvatar)
.then(githubUser => alert(Finished showing ${githubUser.name}));

A

That functions that return a promise can use the .then( ) syntax. This means you can write functions with meaningful names that perform a small task (reusable functions) and then chain them together using .then( ).

40
Q

Are these code fragments equal?

promise.then(f1).catch(f2);

promise.then(f1, f2);

A

no, they are not equal!

That’s because an error is passed down the chain, and in the second code piece there’s no chain below f1.

In other words, .then passes results/errors to the next .then/catch. So in the first example, there’s a catch below, and in the second one there isn’t, so the error is unhandled.

41
Q

When a promise rejects, the control jumps to what ?

A

The closest rejection handler

42
Q

Will this catch block run? explain you answer!

new Promise((resolve, reject) => {
throw new Error(“Whoops!”);
}).catch(console.log); // Error: Whoops!

A

Yes it will run because the code of a promise executor and promise handlers( .then .catch ) have an “invisible try..catch” around them. If an exception happens, it gets caught and treated as a rejection.

43
Q

are these 2 code snippets equivalent? explain your answer?

new Promise((resolve, reject) => {
throw new Error(“Whoops!”);
}).catch(alert); // Error: Whoops!

new Promise((resolve, reject) => {
reject(new Error(“Whoops!”));
}).catch(alert); // Error: Whoops!

A

yes they have the same behavior because the “invisible try..catch” around the executor automatically catches the error and turns it into rejected promise.

44
Q

In a promise executor or promise handler ( .then .catch ) will a programming error be caught by a subsequent catch block?

for example

new Promise((resolve, reject) => {
resolve(“ok”);
}).then((result) => {
weeeee(); // no such function
}).catch(console.log);

A

Yes a .catch not only catches explicit rejections, but also accidental errors in the handlers above it in the promise chain.

45
Q

What is re throwing?

A

Re throwing is when you have a catch block that handles a specific error. After the catch block you can have more .then and .catch blocks to preform operations after the initial error has been dealt with.

new Promise((resolve, reject) => {

throw new Error(“Whoops!”);

}).catch(function(error) {

alert(“The error is handled, continue normally”);

}).then(() => alert(“Next successful handler runs”));

46
Q

What does the following demonstrate? the /* doesn’t run here */ part

new Promise((resolve, reject) => {

throw new Error(“Whoops!”);

}).catch(function(error) { // (*)

if (error instanceof URIError) {
// handle it
} else {
alert(“Can’t handle such error”);

throw error;    }

}).then(function() {
/* doesn’t run here */
}).catch(error => { // (**)

alert(The unknown error has occurred: ${error});
// don’t return anything => execution goes the normal way

});

A

It demonstrates that an error thrown in a .catch handler will be caught by the invisible try catch block around the .catch. This will move execution to the nearest error handler which is the () catch block. This means the code block /* doesn’t run here */ won’t run as execution will move straight to the () .catch.

47
Q

Will this error throw trigger the catch block?

new Promise(function(resolve, reject) {
setTimeout(() => {
throw new Error(“Whoops!”);
}, 1000);
}).catch(alert);

A

No the catch block will not be executed.
The Error is thrown in an asynchronous callback so the promise executor cannot handle it.
The code sequence would run like this

  • promise executor runs (has an invisible try catch around it)
  • setTimeOut attaches callback function to an event
  • promise executor finishes running.
  • setTimeout callback is called when event triggers and has no try catch around it (unhandled error)
48
Q

There are 6 static methods of the Promise class, what are they? Which is the most commonly used in practice?

A

Promise.all
Promise.allSettled
Promise.race
Promise.any
Promise.resolve
Promise.reject

Of all these, Promise.all is probably the most commonly used in practice.

49
Q

What does Promise.all take as an argument and what does it return?

A

Promise.all takes an iterable (usually, an array of promises) and returns a new promise.

50
Q

When the promise returned from a call to Promise.all resolves what is the result.

A

The result is an array of results from each promise inside the Promise.all.

Promise.all([
new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3
]).then(console.log); // [1, 2, 3]

51
Q

What will the result contain from the following Promise?

Promise.all([
new Promise((resolve) => setTimeout(() => resolve(“Hello”), 3000)), // 3 seconds
new Promise((resolve) => setTimeout(() => resolve(“There”), 2000)), // 2 seconds
new Promise((resolve) => setTimeout(() => resolve(“tom”), 1000)), // 1 second
]).then(console.log);

A

[‘Hello’, ‘There’, ‘tom’]

The order of the results array is based upon the order of the promises provided to Promise.all.

52
Q

What is Promisification?

A

“Promisification” is a long word for a simple transformation. It’s the conversion of a function that accepts a callback into a function that returns a promise.

53
Q

What will the output for the following code be ? why?

let promise = Promise.resolve();
promise.then(() => console.log(“promise done!”));
console.log(“code finished”);

A

code finished
promise done!

When a promise is ready (in this case resolved), its .then/catch/finally handlers are put into the microtask queue; they are not executed yet. When the JavaScript engine becomes free from the current code, it takes a task from the queue and executes it.

54
Q

What is the output of the following code and why?

let promise1 = Promise.resolve();
let promise2 = Promise.resolve();

promise1
.then(() => console.log(1))
.then(() => console.log(2));

promise2
.then(() => console.log(3))
.then(() => console.log(4))

A

1324

promise 1 and promise 2 have console.log(1) and console.log(3) event handlers directly attached, so these two goes into the event queue. after the global code is done executing, console.log(1) handler is first brought back to the call stack to be executed. after it is done, it returns a promise whose handler is console.log(2) it goes to the event queue for now. Next the console.log(3) is brought back from the event queue, and it also returns a promise whose handler i.e. the console.log(4) is stored in the event queue.

Currently console.log(1) and console.log(3) is printed, and the handlers for these promises are (console.log(2), console.log(4)) is stored inside the event queue. Now as there are no global code remaining these two remaining handlers will be executed so the final order become

1,3,2,4

55
Q

What will the following code print? Why?

const myFunc = async () => {
console.log(“async func”);
};
const result = myFunc();
console.log(“result”, result);

A

“async func”
“result Promise{<fulfilled>: undefined}"</fulfilled>

We get a promise because async functions always return a promise.
it is fulfilled because there is no await in the async function AND no error occured.
Its result is undefined because the function returns nothing.

56
Q

What will the following code print? Why?

const myFunc = async () => {
console.log(“async func”);
await 2;
};
const result = myFunc();
console.log(“result”, result);

A

async func
result Promise{<pending>}</pending>

We get a promise because async functions always return a promise.
The promise if pending because we are awaiting the number 2.

57
Q

await literally suspends the function execution until the promise settles, and then resumes it with the promise result. Why is this beneficial for the JavaScript engine?

A

It is beneficial because it doesn’t cost any CPU resources, the JavaScript engine can do other jobs in the meantime: execute other scripts, handle events, etc. It frees up the stack.

58
Q

In modern browsers, await on top level works just fine, when we’re inside a module. What is the solution if If we’re not using modules, or older browsers must be supported?

// we assume this code runs at top level, inside a module
let response = await fetch(‘/article/promise-chaining/user.json’);
let user = await response.json();

console.log(user);

A

Wrapping it in an anonymous async function.

(async () => {
let response = await fetch(‘/article/promise-chaining/user.json’);
let user = await response.json();
console.log(user);
})();

59
Q

How does await work when it is used to await a thenable?

async function f() {
// waits for 1 second, then result becomes 2
let result = await new Thenable(1);
alert(result);
}

A

If await gets a non-promise object with .then, it calls that method providing the built-in functions resolve and reject as arguments (just as it does for a regular Promise executor). Then await waits until one of them is called (in the example above it happens in the line (*)) and then proceeds with the result.

60
Q

This is based on my current understanding… might be nonsense

When you have an async function and it does not return a value. If you await the function when does the returned Promise resolve?

A

The returned Promise resolves when the function completes. You can see this in the code below. The Promise is fulfilled but the result is undefined as the function returned nothing. The function finished running so the Promise is resolved.

const result = myAsyncFunc();
result will be: Promise{<fulfilled>: undefined}</fulfilled>

If you await you get the result from the asyn func when it resolves.
const result = await myAsyncFunc();
result will be: undefined

In other words the promise resolves when it receives the return value of the function, in this case the return value is undefined.

61
Q

Can you declare async class methods? Write a code example.

A

Yes, To declare an async class method, just prepend it with async:

class Waiter {
async wait() {
return await Promise.resolve(1);
}
}

new Waiter()
.wait()
.then(alert); // 1 (this is the same as (result => alert(result)))

62
Q

The async keyword before a function has two effects on the function what are they?

A
  1. Makes the function always return a promise.
  2. Allows await to be used inside the function.
63
Q

What will console.log output in the following code? why?

async function f() {
nonExistantFunc();
}
const result = f();
console.log(result);

A

Promise{<rejected>: ReferenceError: nonExistantFunc is not defined
at f (file:///C:/Users/tmann24/Documents/practic…}</rejected>

The async function always returns a Promise. as we are not using await the actual Promise will be returned into the result variable. The nonExistantFunc creates an error so the Promise rejects. This means result is a Rejected Promise.

64
Q

What will console.log output in the following code? why?

async function f() {
nonExistantFunc();
}
const result = await f();
console.log(“result”, result);

A

Trick question! You won’t see the output for the console.log as the console.log won’t run.
nonExistantFunc() will cause an error and return a rejected Promise.
When you await a rejected Promise, an exception is generated — same as if throw error were called at that very place. This stops the script execution as the exception is unhandled.

if we don’t await the console.log runs and we see this output:
Promise{<rejected>: ReferenceError: nonExistantFunc is not defined
at f (file:///C:/Users/tmann24/Documents/practic…}</rejected>

When we don’t await the Error stays inside the Promise so script execution continues and we see the console.log containing the rejected Promise and Error.

65
Q

The await keyword before a promise makes JavaScript wait until that promise settles, and then:

A

If it’s an error, an exception is generated — same as if throw error were called at that very place.
Otherwise, it returns the result.

66
Q

Is the following code going to work as expected?

const order = (time, work) => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(work());
      }, time);
    });
  };

  order(2000, () => {
    console.log("order placed");
  })
    .then(() => {
      order(3000, () => console.log("The fruit is cut"));
    })
    .then(() => {
      order(3000, () => console.log("The topping is added"));
    });
A

no, “The fruit is cut” and “The topping is added” will output at the same time.

The function order() returns a Promise. Within the .then() calls you need to return a Promise so that the following .then() is a method on a Promise. Adding a return will make it work as expected.

const order = (time, work) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(work());
}, time);
});
};

  order(2000, () => {
    console.log("order placed");
  })
    .then(() => {
      return order(3000, () => console.log("The fruit is cut"));
    })
    .then(() => {
      return order(3000, () => console.log("The topping is added"));
    });
67
Q

What does the .then() method return?

A

Returns a new Promise immediately. This new promise is always pending when returned, regardless of the current promise’s status.

68
Q

What will be the output for the following code?

Promise.all([
new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 3000);
}),
2,
3,
]).then(console.log);

A

[1,2, 3]
Normally, Promise.all(…) accepts an iterable (in most cases an array) of promises. But if any of those objects is not a promise, it’s passed to the resulting array “as is”.

69
Q

What does Promise.allSettled( ) do and what does it accept and return.

A

Promise.allSettled( ) accepts an iterable in most cases an array of Promises. It then waits for any Promises in the iterable to settle and returns an array of results with the following objects.
{status:”fulfilled”, value:result} for successful responses,
{status:”rejected”, reason:error} for errors.

70
Q

What is the use case for Promise.settled( ) ?

A

When we don’t require that all the Promises are resolved. For example if we are making network requests for news stories, if one fails we still want to see the rest and render them on screen.

71
Q

What does Promice.race( ) do?

A

Promise.race( ) waits only for the first settled promise and gets its result (or error).

72
Q

What does Promise.any( ) do?

A

Similar to Promise.race, but waits only for the first fulfilled promise and gets its result. If all of the given promises are rejected, then the returned promise is rejected with AggregateError – a special error object that stores all promise errors in its errors property.

73
Q

What will the output be for the following code? why?

Promise.race([
new Promise((resolve, reject) => setTimeout(() => resolve(1), 10000)),
new Promise((resolve, reject) =>
setTimeout(() => reject(new Error(“Whoops!”)), 2000)
),
new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000)),
])
.then(console.log)
.catch(console.log);

A

Error: Whoops!

Promise.race returns the first Promise to settle and in this case it will be the Promise that rejects after 2 seconds. So the log prints the error message.