[2.0 / next] <Errored> recovery shows a pending memo's answer to an older input beside the new input

Đã đóng
#4,592 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
20/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
javascript, typescript
Lĩnh vực
frontend

Hướng nghiên cứu

Start with the two vitest cases in packages/web/test/, which run the same scenario with and without a Loading wrapper inside Errored. Run npx vitest run in packages/web to see the third frame fail with s=1a=10b=21. The fix belongs in how Errored decides it has recovered while memos a and b are still pending on the new input. Done when both tests pass and the frame shows error until a:1 resolves.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Describe the bug

a and b both ask by s. b's first question rejects, so <Errored> shows its fallback. Then s changes and both memos ask again. When b:1 resolves while a:1 is still out, <Errored> recovers and shows s=1a=10b=21. Here a=10 is the answer for s = 0, shown beside s=1. The frame becomes whole only when a:1 lands.

The same happens when the content is wrapped in a <Loading>.

Found by checking every frame of generated ryansolid/reactivescript programs, compiled onto Solid, against F-1.

Your Example Website or App

The vitest spec below (in packages/web/test/), on next @ 77be406ca.

Steps to Reproduce the Bug or Issue
import { render } from "@solidjs/web";
import { createMemo, createSignal, Errored, flush, Loading } from "solid-js";
import { expect, it } from "vitest";

const tick = async () => { for (let i = 0; i < 2; i++) { await new Promise(r => setTimeout(r, 0)); flush(); } };

async function run(boundary: "none" | "loading") {
  const flights = new Map<string, { resolve: (v: number) => void; reject: (e: Error) => void }>();
  const ask = (key: string) => new Promise<number>((resolve, reject) => flights.set(key, { resolve, reject }));
  const [s, setS] = createSignal(0);
  const el = document.createElement("div");
  const frames: string[] = [];
  const dispose = render(() => {
    const a = createMemo(() => ask("a:" + s()));
    const b = createMemo(() => ask("b:" + s()));
    const content = () => (<><p>s={s()}</p><p>a={a()}</p><p>b={b()}</p></>);
    return (
      <Errored fallback={<p>error</p>}>
        {boundary === "loading" ? <Loading fallback={<p>loading</p>}>{content()}</Loading> : content()}
      </Errored>
    );
  }, el);
  await tick();
  flights.get("a:0")!.resolve(10); await tick();
  flights.get("b:0")!.reject(new Error("boom")); await tick(); frames.push(el.textContent!);
  setS(1); flush(); await tick();                frames.push(el.textContent!);   // a:1 and b:1 asked
  flights.get("b:1")!.resolve(21); await tick();  frames.push(el.textContent!);   // b recovers; a:1 is still out
  flights.get("a:1")!.resolve(11); await tick();  frames.push(el.textContent!);
  dispose();
  return frames;
}

it("no boundary: <Errored> recovery does not show a pending memo's stale value beside its new input", async () => {
  expect(await run("none")).toEqual(["error", "error", "error", "s=1a=11b=21"]);
});

it("inside <Loading>: <Errored> recovery does not show a pending memo's stale value beside its new input", async () => {
  expect(await run("loading")).toEqual(["error", "error", "error", "s=1a=11b=21"]);
});

npx vitest run in packages/web. Both tests fail on the third frame, which is s=1a=10b=21 instead of error.

Expected behavior

The recovery waits until every memo in the content can answer the current s, or shows the content's own pending state. It never shows a's answer for an older s beside the new s (F-1, D-39).

Platform
  • OS: macOS
  • Browser: n/a (jsdom)
  • Version: solid-js 2.0.0-rc.20, next @ 77be406ca
Ngôn ngữ chính
TypeScript
Star
36.2k
Fork
1.1k
Merge trung bình
10 giờ 39 phút
Pull request đã merge (30 ngày)
500

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của solidjs/solid

Tất cả issue của solidjs/solid

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.