Debugging Pitfalls: Async forEach and Slice Memory Sharing in JavaScript

From last Thursday until just now (Saturday), two issues confused me a lot:

forEach is synchronous, not asynchronous

This is a fundamental concept, but problems can arise when you assume a block of code will execute synchronously while using forEach. For some reason, if that block of code becomes asynchronous, it could lead to unexpected issues.

slice creates a shallow copy

shortConversation = […systemPrompt, …chatThread.current.slice(-(memoryLength + 2 - 1))];

The slice method causes shortConversation and chatThread to share part of the memory, which led to unexpected behaviors.

The corrected code is as follows:

shortConversation = [...systemPrompt, ...structuredClone(chatThread.current.slice(-(memoryLength + 2 - 1)))];

Using structuredClone ensures that shortConversation and chatThread are completely independent.