• Skip to main content
  • Skip to search
  • Skip to select language
  • Sign up for free
  • English (US)

Using promises

A Promise is an object representing the eventual completion or failure of an asynchronous operation. Since most people are consumers of already-created promises, this guide will explain consumption of returned promises before explaining how to create them.

Essentially, a promise is a returned object to which you attach callbacks, instead of passing callbacks into a function. Imagine a function, createAudioFileAsync() , which asynchronously generates a sound file given a configuration record and two callback functions: one called if the audio file is successfully created, and the other called if an error occurs.

Here's some code that uses createAudioFileAsync() :

If createAudioFileAsync() were rewritten to return a promise, you would attach your callbacks to it instead:

This convention has several advantages. We will explore each one.

A common need is to execute two or more asynchronous operations back to back, where each subsequent operation starts when the previous operation succeeds, with the result from the previous step. In the old days, doing several asynchronous operations in a row would lead to the classic callback pyramid of doom:

With promises, we accomplish this by creating a promise chain. The API design of promises makes this great, because callbacks are attached to the returned promise object, instead of being passed into a function.

Here's the magic: the then() function returns a new promise , different from the original:

This second promise ( promise2 ) represents the completion not just of doSomething() , but also of the successCallback or failureCallback you passed in — which can be other asynchronous functions returning a promise. When that's the case, any callbacks added to promise2 get queued behind the promise returned by either successCallback or failureCallback .

Note: If you want a working example to play with, you can use the following template to create any function returning a promise:

The implementation is discussed in the Creating a Promise around an old callback API section below.

With this pattern, you can create longer chains of processing, where each promise represents the completion of one asynchronous step in the chain. In addition, the arguments to then are optional, and catch(failureCallback) is short for then(null, failureCallback) — so if your error handling code is the same for all steps, you can attach it to the end of the chain:

You might see this expressed with arrow functions instead:

Note: Arrow function expressions can have an implicit return ; so, () => x is short for () => { return x; } .

doSomethingElse and doThirdThing can return any value — if they return promises, that promise is first waited until it settles, and the next callback receives the fulfillment value, not the promise itself. It is important to always return promises from then callbacks, even if the promise always resolves to undefined . If the previous handler started a promise but did not return it, there's no way to track its settlement anymore, and the promise is said to be "floating".

By returning the result of the fetch call (which is a promise), we can both track its completion and receive its value when it completes.

Floating promises could be worse if you have race conditions — if the promise from the last handler is not returned, the next then handler will be called early, and any value it reads may be incomplete.

Therefore, as a rule of thumb, whenever your operation encounters a promise, return it and defer its handling to the next then handler.

Even better, you can flatten the nested chain into a single chain, which is simpler and makes error handling easier. The details are discussed in the Nesting section below.

Using async / await can help you write code that's more intuitive and resembles synchronous code. Below is the same example using async / await :

Note how the code looks exactly like synchronous code, except for the await keywords in front of promises. One of the only the tradeoffs is that it may be easy to forget the await keyword, which can only be fixed when there's a type mismatch (e.g. trying to use a promise as a value).

async / await builds on promises — for example, doSomething() is the same function as before, so there's minimal refactoring needed to change from promises to async / await . You can read more about the async / await syntax in the async functions and await references.

Note: async/await has the same concurrency semantics as normal promise chains. await within one async function does not stop the entire program, only the parts that depend on its value, so other async jobs can still run while the await is pending.

Error handling

You might recall seeing failureCallback three times in the pyramid of doom earlier, compared to only once at the end of the promise chain:

If there's an exception, the browser will look down the chain for .catch() handlers or onRejected . This is very much modeled after how synchronous code works:

This symmetry with asynchronous code culminates in the async / await syntax:

Promises solve a fundamental flaw with the callback pyramid of doom, by catching all errors, even thrown exceptions and programming errors. This is essential for functional composition of asynchronous operations. All errors are now handled by the catch() method at the end of the chain, and you should almost never need to use try / catch without using async / await .

In the examples above involving listOfIngredients , the first one has one promise chain nested in the return value of another then() handler, while the second one uses an entirely flat chain. Simple promise chains are best kept flat without nesting, as nesting can be a result of careless composition.

Nesting is a control structure to limit the scope of catch statements. Specifically, a nested catch only catches failures in its scope and below, not errors higher up in the chain outside the nested scope. When used correctly, this gives greater precision in error recovery:

Note that the optional steps here are nested — with the nesting caused not by the indentation, but by the placement of the outer ( and ) parentheses around the steps.

The inner error-silencing catch handler only catches failures from doSomethingOptional() and doSomethingExtraNice() , after which the code resumes with moreCriticalStuff() . Importantly, if doSomethingCritical() fails, its error is caught by the final (outer) catch only, and does not get swallowed by the inner catch handler.

In async / await , this code looks like:

Note: If you don't have sophisticated error handling, you very likely don't need nested then handlers. Instead, use a flat chain and put the error handling logic at the end.

Chaining after a catch

It's possible to chain after a failure, i.e. a catch , which is useful to accomplish new actions even after an action failed in the chain. Read the following example:

This will output the following text:

Note: The text "Do this" is not displayed because the "Something failed" error caused a rejection.

Promise rejection events

If a promise rejection event is not handled by any handler, it bubbles to the top of the call stack, and the host needs to surface it. On the web, whenever a promise is rejected, one of two events is sent to the global scope (generally, this is either the window or, if being used in a web worker, it's the Worker or other worker-based interface). The two events are:

Sent when a promise is rejected but there is no rejection handler available.

Sent when a handler is attached to a rejected promise that has already caused an unhandledrejection event.

In both cases, the event (of type PromiseRejectionEvent ) has as members a promise property indicating the promise that was rejected, and a reason property that provides the reason given for the promise to be rejected.

These make it possible to offer fallback error handling for promises, as well as to help debug issues with your promise management. These handlers are global per context, so all errors will go to the same event handlers, regardless of source.

In Node.js , handling promise rejection is slightly different. You capture unhandled rejections by adding a handler for the Node.js unhandledRejection event (notice the difference in capitalization of the name), like this:

For Node.js, to prevent the error from being logged to the console (the default action that would otherwise occur), adding that process.on() listener is all that's necessary; there's no need for an equivalent of the browser runtime's preventDefault() method.

However, if you add that process.on listener but don't also have code within it to handle rejected promises, they will just be dropped on the floor and silently ignored. So ideally, you should add code within that listener to examine each rejected promise and make sure it was not caused by an actual code bug.

Composition

There are four composition tools for running asynchronous operations concurrently: Promise.all() , Promise.allSettled() , Promise.any() , and Promise.race() .

We can start operations at the same time and wait for them all to finish like this:

If one of the promises in the array rejects, Promise.all() immediately rejects the returned promise and aborts the other operations. This may cause unexpected state or behavior. Promise.allSettled() is another composition tool that ensures all operations are complete before resolving.

These methods all run promises concurrently — a sequence of promises are started simultaneously and do not wait for each other. Sequential composition is possible using some clever JavaScript:

In this example, we reduce an array of asynchronous functions down to a promise chain. The code above is equivalent to:

This can be made into a reusable compose function, which is common in functional programming:

The composeAsync() function accepts any number of functions as arguments and returns a new function that accepts an initial value to be passed through the composition pipeline:

Sequential composition can also be done more succinctly with async/await:

However, before you compose promises sequentially, consider if it's really necessary — it's always better to run promises concurrently so that they don't unnecessarily block each other unless one promise's execution depends on another's result.

Creating a Promise around an old callback API

A Promise can be created from scratch using its constructor . This should be needed only to wrap old APIs.

In an ideal world, all asynchronous functions would already return promises. Unfortunately, some APIs still expect success and/or failure callbacks to be passed in the old way. The most obvious example is the setTimeout() function:

Mixing old-style callbacks and promises is problematic. If saySomething() fails or contains a programming error, nothing catches it. This is intrinsic to the design of setTimeout .

Luckily we can wrap setTimeout in a promise. The best practice is to wrap the callback-accepting functions at the lowest possible level, and then never call them directly again:

The promise constructor takes an executor function that lets us resolve or reject a promise manually. Since setTimeout() doesn't really fail, we left out reject in this case. For more information on how the executor function works, see the Promise() reference.

Lastly, we will look into the more technical details, about when the registered callbacks get called.

In the callback-based API, when and how the callback gets called depends on the API implementor. For example, the callback may be called synchronously or asynchronously:

The above design is strongly discouraged because it leads to the so-called "state of Zalgo". In the context of designing asynchronous APIs, this means a callback is called synchronously in some cases but asynchronously in other cases, creating ambiguity for the caller. For further background, see the article Designing APIs for Asynchrony , where the term was first formally presented. This API design makes side effects hard to analyze:

On the other hand, promises are a form of inversion of control — the API implementor does not control when the callback gets called. Instead, the job of maintaining the callback queue and deciding when to call the callbacks is delegated to the promise implementation, and both the API user and API developer automatically gets strong semantic guarantees, including:

  • Callbacks added with then() will never be invoked before the completion of the current run of the JavaScript event loop.
  • These callbacks will be invoked even if they were added after the success or failure of the asynchronous operation that the promise represents.
  • Multiple callbacks may be added by calling then() several times. They will be invoked one after another, in the order in which they were inserted.

To avoid surprises, functions passed to then() will never be called synchronously, even with an already-resolved promise:

Instead of running immediately, the passed-in function is put on a microtask queue, which means it runs later (only after the function which created it exits, and when the JavaScript execution stack is empty), just before control is returned to the event loop; i.e. pretty soon:

Task queues vs. microtasks

Promise callbacks are handled as a microtask whereas setTimeout() callbacks are handled as task queues.

The code above will output:

For more details, refer to Tasks vs. microtasks .

When promises and tasks collide

If you run into situations in which you have promises and tasks (such as events or callbacks) which are firing in unpredictable orders, it's possible you may benefit from using a microtask to check status or balance out your promises when promises are created conditionally.

If you think microtasks may help solve this problem, see the microtask guide to learn more about how to use queueMicrotask() to enqueue a function as a microtask.

  • async function
  • Promises/A+ specification
  • We have a problem with promises on pouchdb.com (2015)

Is it possible to assign promise data value to outside variable?

I want to do something like:

In this example, I get variable undefined.

Are those two functions ([this.getReports(), this.getUser()]).) called synchronously?

I’m new to this, many thanks!

variable will not be defined until the promises resolve, and generally speaking the only way to know when that is is to only access it from within the then clause. If you can’t do that (such as when it needs to be referenced from a template), it’s generally easiest to initialize it to a dummy value first.

I’m not quite sure what you’re asking, but if you mean “can I be certain that getReports has finished before getUser starts?”, the answer is no. You can be certain that both have finished by the time you are in the then .

I see. But in this example I am assigning variable from then clause. And still getting the same undefined ?

I spoke earlier about how variable will be undefined until the promise resolves. If you are trying to use the value in any situation that may be earlier, you will be disappointed. Either ensure that that never happens (which is harder than you think, and probably not what your users want), or give it a dummy value earlier.

what do you mean by dummy value? how would that help if I don’t need the dummy value and need the data[0] ?

do you think something like this would work?

Sorry for the confusion, I’m just trying to understand.

Hi @vikneke ,

Promises are asynchronous, meaning that the code above is not guaranteed (nor expected) to execute every line immediately after the previous.

This StackOverflow topic will explain the problem and multiple solutions in great detail.

Thanks, Ryan

By the way, this is a “dummy” value…

…you’re purposefully assigning an incorrect value to a variable. It’s obvious that it’s wrong, but you’re expecting your code to step in and later assign a proper value.

In Angular, you often see “loading…” or something of the sort used as “dummy” values.

How to Use promises in JavaScript

  • 12 min read
  • December 2, 2021

javascript assign promise to variable

JavaScript is a synchronous language, yet sometimes asynchronous behavior is required. For example, you may need to use an asynchronous function while waiting for data to be fetched from an API, or while waiting for a site’s images to load. Such procedures take time to complete, and a native blocking approach would negatively impact user experience. As such, the concept of promises was created.

In short, a promise is JavaScript’s way of telling us: “I’m on it. When I’m done, I’ll send you the result”. It is an assurance that the calling thread will receive a result at a later point in time. This assurance allows the main thread of execution to continue, instead of needing to block the execution’s progress until the method being called returns properly.

A promise has three states – one initial state and two end states:

pending – This is the initial state. This state indicates that the request is pending, and leads to one of the other two states upon completion. fulfilled – This is an end state that indicates that the operation was completed successfully . rejected – This is an end state that indicates that the operation has failed .

The syntax for a promise is straightforward. First create a promise using the keyword new along with the keyword Promise (with capital P). Next, provide a callback function as a parameter – this function will handle the two possible end states: fulfillment or rejection . The syntax below demonstrates how to use a Promise:

const promise = new Promise(( resolve , reject )= > { // Additional statement (s) here resolve ( resultOfSuccess ) reject ( resultOfFailure ) }

This syntax uses an arrow function as the callback. Other than the variable name, no changes are required here. You can optionally provide statements to execute as a part of this function. These statements should work to determine the required resolution of the action taken – this can be a condition, a URL to connect to, or any other statement that supports the promise’s resolution. Results are returned by calling the resolve() or reject() parameters with one of two values:

resultOfSuccess: the return value in case of a successful execution.

resultOfFailure: the return value in case of a failed execution.

Next, we’ll explore these concepts with some sample code.

Basic Promise example

Imagine that, for some reason, you wanted to write a calculator that only works half of the time. In code, a “bad” calculator might look something like this:

In the above code, badCalc() returns a promise . Therefore we have a guarantee to get a value back, but it won’t always be the product of num1 and num2 . This is because this promise is set to resolve (or fulfill) in approximately half the cases, while it will fail (or reject ) in the other half of cases.

When the function is successful , you will receive the expected result: i= 20 Promise {<fulfilled>: 420} . In the case of a failure , though, you’ll see a rejected promise: i= 23 Promise {<rejected>: “Oopsy…”} returned. In both cases the result is wrapped up in a promise object, from which we will need to extract the return values. In our fulfilled case above, this means we can’t use the result in further calculations – adding “7” to the result of badCalc (“420”) will not work because we are not working with objects directly. You can see this happening in the following code:

In the above code, you can see that the value “7” is simply appended as a string to the promise object’s string output value, which is definitely not what we intended. This is due to the result of badCalc being a promise object, rather than the numeric result we were hoping to see.

Asynchronous functions enable us to work with promises and their resolution.

There are two ways to handle promise results:

.then() , which is called as a callback upon completion of the promise async / await , which forces the current thread of execution to wait for the promise to complete

This page focuses mostly on the second option. It’s newer, it’s cleaner, and it’s a lot more readable. But first, we’ll review the callback pattern, which is implemented using .then() .

Promise.prototype.then() – basic examples

The following example shows how to use .then() to handle promises and promise resolution:

The above code demonstrates how to use .then() so that you are able to use the return value of badCalc() without needing any extra steps. We simply store the return value in a variable, res . This allows us to operate on that value later using the .then() method.

.then() takes a callback function as its argument. In the above example, res is being passed as a parameter to this callback. Using console.log() , you can see that res is of type Number . This makes it possible to use the result directly, letting us add 7 to the value without running into the type issue we encountered before. The expected log output of the above function with an argument of i=0 would be: i= 0 res: 7 .

However, the log is only displayed for the “good” calculations – function calls where the promise resolution is fulfilled, or successful. We need to add a bit more code to handle the rejected case and allow for our “Oopsy…” string to be printed. To accomplish this, we need to tell our .then() handler what to do with rejected promises. The following code shows how this is done:

In the above code, in case of a successful operation, ( res + 7 ) will be printed to the console, and “ Oopsy …” will be printed to the console when the operation fails.

Note: the word ‘ failure ’ in the above code sample can be changed to any other word, it establishes a promise resolution similar to the result handler above, creating a function with a single parameter named “failure” that will contain details on the error encountered.

The above provides the basics of using the .then() syntax for handling promise resolution. Next, let’s take a look at using the async / await syntax.

async / await

The async-await syntax helps with readability, allowing you to write asynchronous code as if it were following synchronous call patterns.

To enable this method of communication, you’ll need to modify your function prototype. In the declaration of the function prototype, before the word ‘ function ’, add the keyword async . This signals to JavaScript that this method will handle promise resolutions.

Next, we edit the function itself to add the keyword await to our asynchronous function call. This keyword tells JavaScript what to wait for when it is processing, and when the execution thread reaches this line the call will block until the promise is resolved. When the value is returned from this asynchronous function, the function code will continue its execution as normal. Other parts of your application’s code are unaffected, and continue running without issue. That’s asynchronous programming in a nutshell!

Here is the general syntax for using the async / await promise resolution method:

async function name (parameters) { // Your statement (s) here! }

The syntax above has the following components:

name : the name of the function parameters : the names of arguments to be passed to the function statements : the body of the function where the await mechanism can be used.

The following simple example adapts our badCalc() handler to work properly with the async / await pattern:

In the above example, the word async was added to the getMul() function declaration. Inside the function’s scope, await appears before badCalc() , telling JavaScript to await the result of this call before moving on. The return value received is the value we need for the following console.log() statement.

Try…catch statement

The above code uses the try and catch keywords. These are used to manage exception handling , giving us additional flexibility when working with functions that may throw an error. Let’s explore these keywords in a bit more depth.

We’ll start with try , which tells the function “try to run the following code.” The statements in this block are executed as any other code block would be, until the code either completes or encounters an error.

If the code encounters an error, the catch block is invoked to handle it. The error is then “caught”. An error that is “caught” is regarded as a “ handled error ” in JavaScript , and the code will be allowed to continue despite the handled exception. In the example above, about half of the attempted calls to badCalc() will be rejected. Without the catch block, the function will fail with the first error, halting the execution of the code at the point of failure and likely bringing down the entire application as a result.

Try…catch blocks are very powerful, and should be used whenever dealing with promises as, unfortunately, not all promises are fulfilled. The try…catch block allows us to handle these unfulfilled promises gracefully, allowing the code execution to continue uninterrupted.

In the code above, a “good” return value from badCalc() will print i= 11 res: 132 to the console. In the event of a failure, the catch block above will print our Oopsy… error message to the console.

Promise.all()

Many functions require multiple data calls to pull in all the information needed to perform a given task. The function itself cannot continue until it has all of the information it needs from the dependent asynchronous functions. Think of these situations as being like a party that can only begin when all of the invited guests have arrived. Promise.all() allows us to manage this complexity.

Let’s explore this with an example. In our example, we cannot begin the party until all three of the invited guests have arrived. In the following code, we illustrate this concept with four functions. We have a function for each guest that codifies their arrival at the party, and a marshalling function that handles the execution needed once all three party attendees have arrived:

In the above example, each arrival function runs with a custom delay. Person A arrives after 2 seconds, person B arrives after 500 milliseconds, and person C arrives after 3 seconds.

As party() is an async function , both console.log() statements will occur after person C arrives, or 3 seconds after the request was made. We catch all of these promises using the await keyword, and provide all of our promise-generating functions as an array argument to Promise.all() . The code only continues when all promises have been completed, and the results are stored in variables a, b, and c respectively.

You can perform the same task using only a single return value, instead of an array of three return values. To do so, use the following syntax:

This code produces a similar result to the first set of example code, but faces a couple issues. First, it will not be able to log individual results from each of the aggregated promises. Secondly, it will not provide any return value to the variable ‘waiting’. This approach prevents you from using the values returned from the promises that are being monitored.

Note: Promise.all() receives an array of promises as its parameter . Promise.all() resolves all of the promises, so there is no need to use try…catch functionality here.

The Promise.all() method has the following syntax:

await Promise.all (array of promises)

Promise.all() requires that you pass in the promises to be monitored as an array. Each item in the array is a promise that needs to be resolved. In the example above, we pass in an array with all three of our invitee functions, each containing a promise. This gives us the array of promises that Promise.all() is looking for. Promise.all() then waits for the three promises to complete, returning their results once the promises have resolved.

Related Articles

JavaScript – How to Use setTimeout

JavaScript – How to Use functions

JavaScript – How to Use Array reduce method

Related Posts

How to get an object’s keys and values in javascript.

  • December 16, 2020

In JavaScript, getting the keys and values that comprise an object is very easy. You can retrieve each object’s keys, values, or both combined into an

How to Use the Assignment Operator in JavaScript

  • November 30, 2020

The Assignment operator is used to assign a value to a variable. Assignment (=) The assignment operator simply assigns the value of the right operand to

How to Use the for…in Statement in JavaScript

  • December 2, 2020

The for…in statement is used to loop through an object’s properties. Basic for…in loop example The following code demonstrates a basic example using the for…in statement

javascript assign promise to variable

Get promise result then pass the result into a variable

Abdullah Al Naiem's profile photo

Abdullah Al Naiem

I know my code is wrong, but my approach is something like this code

Ibrahim's profile photo

You should assign a promise to a declared variable named makeServerRequest. Your promise should receive a function with resolve and reject as parameters

Tell us what’s happening:

Your code so far

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36 .

Challenge: Create a JavaScript Promise

Link to the challenge:

Hello there.

Do you have a question?

If so, please edit your post to include it in the Tell us what’s happening section.

The more information you give us, the more likely we are to be able to help.

IMAGES

  1. Promise Chaining in JavaScript

    javascript assign promise to variable

  2. 35 Javascript Declare A Variable

    javascript assign promise to variable

  3. The Definitive Guide to the JavaScript Promises

    javascript assign promise to variable

  4. 32 How To Assign Value In Javascript

    javascript assign promise to variable

  5. 35 How To Declare A Variable In Javascript

    javascript assign promise to variable

  6. 40 Javascript Assign Function To Variable

    javascript assign promise to variable

VIDEO

  1. Копирование с помощью Object.assign в JavaScript

  2. assign value to javascript variables ||#google #html #coding #javascript #vairal #programing

  3. 16.3 JavaScript assign Value of one field to other in SAP Adobe forms

  4. javascript assign& modify part-11 || bangla

  5. JavaScript Promise allSettled

  6. 37- Methods uses for array In JavaScript up

COMMENTS

  1. What Is a Qualitative Variable?

    Qualitative variables are those with no natural or logical order. While scientists often assign a number to each, these numbers are not meaningful in any way. Examples of qualitative variables include things such as color, shape or pattern.

  2. What Is a PR Bond?

    A personal recognizance, or PR bond, is the release of a defendant without any bail, according to Boulder County government in Colorado. While there is a dollar amount assigned to the bond, the fee is waived and the defendant must sign the ...

  3. What Is the Meaning of Experimental Research?

    In experimental research, researchers use controllable variables to see if manipulation of these variables has an effect on the experiment’s outcome. Additionally, subjects of the experimental research are randomly assigned to prevent bias ...

  4. Assign value from successful promise resolve to external variable

    This is the default way Javascript works. This was the exact reason Promises were introduced, so you could ask the interpreter to push the value

  5. How can I assign a variable to the response of a promise?

    You're misunderstanding how promises work. Go read up on them first and you should figure it out. Also read about javascript event loop.

  6. How to store a value returned by a promise in a variable?

    Promises are another way to handle asynchronous programming in JavaScript. When created, a promise starts in the pending state and enters the

  7. Assigning the Value of a Promise to a Variable in Javascript

    Assigning a promise to a variable, not the result or executed Promise? ... A promise can be returned from a function and assigned to a variable.

  8. Using promises

    A Promise is an object representing the eventual completion or failure of an asynchronous operation. Since most people are consumers of

  9. Set External Variable to Value Resolved from Successful Promise

    Assign value from successful promise resolve to external variable, Get the value of a promise and assign to variable, Resolve Javascript

  10. Is it possible to assign promise data value to outside variable?

    Is it possible to assign promise data value to outside variable? I want to do something like: var variable;

  11. How to Use promises in JavaScript

    Other than the variable name, no changes are required here. You can optionally provide statements to execute as a part of this function. These

  12. Get promise result then pass the result into a variable

    Here's my code and I want to assign promise result into a variable then do the same thing again function ok(x){ return new Promise((resolve

  13. You should assign a promise to a declared variable named

    4147.135 Safari/537.36 . Challenge: Create a JavaScript Promise. Link to the challenge: freecodecamp.org · freeCodeCamp.org. Learn to code

  14. How to Resolve a Promise from Outside in JavaScript

    To resolve a promise from outside in JavaScript, assign the resolve callback to a variable defined outside the Promise constructor scope