Back to Biomejs

noNestedPromises

src/content/docs/linter/rules/no-nested-promises.mdx

latest7.8 KB
Original Source

import { Tabs, TabItem } from '@astrojs/starlight/components';

<Tabs> <TabItem label="JavaScript (and super languages)" icon="seti:javascript"> :::caution This rule is part of the [nursery](/linter/#nursery) group. This means that it is experimental and the behavior can change at any time. ::: ## Summary - Rule available since: `v2.3.15` - Diagnostic Category: [`lint/nursery/noNestedPromises`](/reference/diagnostics#diagnostic-category) - This rule doesn't have a fix. - The default severity of this rule is [**information**](/reference/diagnostics#information). - Sources: - Same as [`promise/no-nesting`](https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/no-nesting.md)

How to configure

json
{
	"linter": {
		"rules": {
			"nursery": {
				"noNestedPromises": "error"
			}
		}
	}
}

Description

Disallow nested .then() or .catch() promise calls.

Nesting .then() or .catch() calls defeats the purpose of promises, which is to create a flat chain of asynchronous operations. Nested promise callbacks can make code harder to read and maintain.

However, nesting is allowed when the nested callback references variables from the outer scope, as flattening would break the code in such cases.

Examples

Invalid

js
doThing().then(function() { return a.then() })
<pre class="language-text"><code class="language-text">code-block.js:1:38 <a href="https://biomejs.dev/linter/rules/no-nested-promises">lint/nursery/noNestedPromises</a> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">Avoid nesting promises.</span> <strong><span style="color: Tomato;">&gt;</span></strong> <strong>1 │ </strong>doThing().then(function() &#123; return a.then() &#125;) <strong> │ </strong> <strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> <strong>2 │ </strong> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">Nesting promises can lead to harder-to-read code because it creates multiple levels of indentation and makes the flow of asynchronous operations less clear.</span> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">Consider refactoring the code to use promise chaining (foo.then().then()) instead of nesting.</span> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit </span><span style="color: lightgreen;"><a href="https://biomejs.dev/linter/#nursery">https://biomejs.dev/linter/#nursery</a></span><span style="color: lightgreen;"> for more information.</span> </code></pre>
js
doThing().then(() => b.catch())
<pre class="language-text"><code class="language-text">code-block.js:1:24 <a href="https://biomejs.dev/linter/rules/no-nested-promises">lint/nursery/noNestedPromises</a> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">Avoid nesting promises.</span> <strong><span style="color: Tomato;">&gt;</span></strong> <strong>1 │ </strong>doThing().then(() =&gt; b.catch()) <strong> │ </strong> <strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> <strong>2 │ </strong> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">Nesting promises can lead to harder-to-read code because it creates multiple levels of indentation and makes the flow of asynchronous operations less clear.</span> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">Consider refactoring the code to use promise chaining (foo.then().then()) instead of nesting.</span> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit </span><span style="color: lightgreen;"><a href="https://biomejs.dev/linter/#nursery">https://biomejs.dev/linter/#nursery</a></span><span style="color: lightgreen;"> for more information.</span> </code></pre>
js
doThing()
  .then(a => getB(a)
    .then(b => getC(b))
  )
<pre class="language-text"><code class="language-text">code-block.js:3:6 <a href="https://biomejs.dev/linter/rules/no-nested-promises">lint/nursery/noNestedPromises</a> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">Avoid nesting promises.</span> <strong>1 │ </strong>doThing() <strong>2 │ </strong> .then(a =&gt; getB(a) <strong><span style="color: Tomato;">&gt;</span></strong> <strong>3 │ </strong> .then(b =&gt; getC(b)) <strong> │ </strong> <strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> <strong>4 │ </strong> ) <strong>5 │ </strong> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">Nesting promises can lead to harder-to-read code because it creates multiple levels of indentation and makes the flow of asynchronous operations less clear.</span> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">Consider refactoring the code to use promise chaining (foo.then().then()) instead of nesting.</span> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit </span><span style="color: lightgreen;"><a href="https://biomejs.dev/linter/#nursery">https://biomejs.dev/linter/#nursery</a></span><span style="color: lightgreen;"> for more information.</span> </code></pre>

Valid

js
// Simple returns
doThing().then(function() { return 4 })
doThing().then(() => 4)
js
// Chained promises (no nesting)
doThing()
  .then(a => getB(a))
  .then(b => getC(b))
js
// Nested but references outer scope variable 'a'
doThing()
  .then(a => getB(a)
    .then(b => getC(a, b))
  )
js
// Promise.resolve/all are fine
doThing().then(function() { return Promise.all([a,b,c]) })
doThing().then(() => Promise.resolve(4))
</TabItem> </Tabs>