Skip to content

$effect.pending() stuck at 1 even though the promise has resolved #16571

@regnstr

Description

@regnstr

Describe the bug

When using await inside the script tag, $effect.pending() seems to be "stuck" at a non-zero value even though the promise has resolved. Clicking any of the buttons in the example will "clear" the $effect.pending() and cause everything to work as expected from then on.

This bug makes showing loading states buggy, since they will never go away on their own.

The repro contains an additional case where an if-block depending on the value of $effect.pending() is permanently stuck. I'm not sure if this is a bug though, because putting an await in a place like that feels a little circular-y and I'm not surprised something broke...

<script lang="ts"> 
  let length = $state(10)
  
  async function generateArray(length: number) {
    const result = new Promise(resolve => setTimeout(() => resolve([...Array(length).keys()]), 500))
    return result;
  }
	
  let testValues = $derived(await generateArray(length))
	$inspect('$effect.pending()', $effect.pending());
</script>

<div>
	<p>Value of length: {length}</p>

	<div>
		<button onclick={() => {console.log('clicked'); length--;}}>-</button>
		<button onclick={() => {console.log('clicked'); length++;}}>+</button>
	</div>
	<p>
		Clicking any of buttons will cause $effect.pending() to become 0 after the promise resolves.
	</p>
	<p>
		Value of $effect.pending(): {$effect.pending()}
	</p>
	
	{#if $effect.pending()}
		<p><strong>Imagine this is a loading indicator that should only be visible while updating data, but it doesn't go away on its own...</strong></p>
	{/if}
		
	<div>
		<span>Values:</span>
		<div style="display: flex; gap: 10px;">
			{#each testValues as value (value)}
				<p>{value}</p>
			{/each}
		</div>
	</div>
</div>

Reproduction

https://svelte.dev/playground/c89e19682d8f42309dfb4cd9c7cf6807?version=5.38.0

Logs

init $effect.pending() 1
clicked
update $effect.pending() 0
clicked
update $effect.pending() 1
update $effect.pending() 0

System Info

Svelte playground

Severity

blocking an upgrade

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions