File size: 5,717 Bytes
780c9fe | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | ---
title: Promise.try()
short-title: try()
slug: Web/JavaScript/Reference/Global_Objects/Promise/try
page-type: javascript-static-method
browser-compat: javascript.builtins.Promise.try
sidebar: jsref
---
The **`Promise.try()`** static method takes a callback of any kind (returns or throws, synchronously or asynchronously) and wraps its result in a {{jsxref("Promise")}}.
## Syntax
```js-nolint
Promise.try(func)
Promise.try(func, arg1)
Promise.try(func, arg1, arg2)
Promise.try(func, arg1, arg2, /* …, */ argN)
```
### Parameters
- `func`
- : A function that is called synchronously with the arguments provided (`arg1`, `arg2`, …, `argN`). It can do anything—either return a value, throw an error, or return a promise.
- `arg1`, `arg2`, …, `argN`
- : Arguments to pass to `func`.
### Return value
A {{jsxref("Promise")}} that is:
- Already fulfilled, if `func` synchronously returns a value.
- Already rejected, if `func` synchronously throws an error.
- Asynchronously fulfilled or rejected, if `func` returns a promise.
## Description
You may have an API that takes a callback. The callback may be synchronous or asynchronous. You want to handle everything uniformly by wrapping the result in a promise. The most straightforward way might be {{jsxref("Promise/resolve", "Promise.resolve(func())")}}. The problem is that if `func()` synchronously throws an error, this error would not be caught and turned into a rejected promise.
The common approach (lifting a function call result into a promise, fulfilled or rejected) often looks like this:
```js
new Promise((resolve) => resolve(func()));
```
But `Promise.try()` is more helpful here:
```js
Promise.try(func);
```
For the built-in `Promise()` constructor, errors thrown from the executor are automatically caught and turned into rejections, so these two approaches are mostly equivalent, except that `Promise.try()` is more concise and readable.
Note that `Promise.try()` is _not_ equivalent to this, despite being highly similar:
```js
Promise.resolve().then(func);
```
The difference is that the callback passed to {{jsxref("Promise/then", "then()")}} is always called asynchronously, while the executor of the `Promise()` constructor is called synchronously. `Promise.try` also calls the function synchronously, and resolves the promise immediately if possible.
`Promise.try()`, combined with {{jsxref("Promise/catch", "catch()")}} and {{jsxref("Promise/finally", "finally()")}}, can be used to handle both synchronous and asynchronous errors in a single chain, and make promise error handling appear almost like synchronous error handling.
Like {{domxref("Window/setTimeout", "setTimeout()")}}, `Promise.try()` accepts extra arguments that are passed to the callback. This means instead of doing this:
```js
Promise.try(() => func(arg1, arg2));
```
You can do this:
```js
Promise.try(func, arg1, arg2);
```
Which are equivalent, but the latter avoids creating an extra closure and is more efficient.
## Examples
### Using Promise.try()
The following example takes a callback, "lifts" it into a promise, handles the result, and does some error handling:
```js
function doSomething(action) {
return Promise.try(action)
.then((result) => console.log(result))
.catch((error) => console.error(error))
.finally(() => console.log("Done"));
}
doSomething(() => "Sync result");
doSomething(() => {
throw new Error("Sync error");
});
doSomething(async () => "Async result");
doSomething(async () => {
throw new Error("Async error");
});
```
In async/await, the same code would look like this:
```js
async function doSomething(action) {
try {
const result = await action();
console.log(result);
} catch (error) {
console.error(error);
} finally {
console.log("Done");
}
}
```
### Calling try() on a non-Promise constructor
`Promise.try()` is a generic method. It can be called on any constructor that implements the same signature as the `Promise()` constructor.
The following is a slightly more faithful approximation of the actual `Promise.try()` (although it should still not be used as a polyfill):
```js
Promise.try = function (func) {
return new this((resolve, reject) => {
try {
resolve(func());
} catch (error) {
reject(error);
}
});
};
```
Because of how `Promise.try()` is implemented (i.e., the `try...catch`), we can safely invoke `Promise.try()` with its `this` set to any custom constructor, and it will never synchronously throw an error.
```js
class NotPromise {
constructor(executor) {
// The "resolve" and "reject" functions behave nothing like the native
// promise's, but Promise.try() just calls resolve
executor(
(value) => console.log("Resolved", value),
(reason) => console.log("Rejected", reason),
);
}
}
const p = Promise.try.call(NotPromise, () => "hello");
// Logs: Resolved hello
const p2 = Promise.try.call(NotPromise, () => {
throw new Error("oops");
});
// Logs: Rejected Error: oops
```
Unlike `Promise()`, this `NotPromise()` constructor _does not_ gracefully handle exceptions while running the executor. But despite the `throw`, `Promise.try()` still catches the exception, passing it to `reject()` to log out.
## Specifications
{{Specifications}}
## Browser compatibility
{{Compat}}
## See also
- [Polyfill of `Promise.try` in `core-js`](https://github.com/zloirock/core-js#promisetry)
- [es-shims polyfill of `Promise.try`](https://www.npmjs.com/package/promise.try)
- [Using promises](/en-US/docs/Web/JavaScript/Guide/Using_promises) guide
- {{jsxref("Promise")}}
- [`Promise()` constructor](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise)
|