如果从另一个功能返回

发布于 2025-02-01 12:31:33 字数 3094 浏览 3 评论 0原文

我想创建createAsyncthunk功能包装器,因为想要在带有参数的一个中重构3个大thunk。这是我的解决方案。

代码

export const getExportThunk = <T>(
  handler: (args: T) => Promise<boolean>,
  route: string,
  successText: string
) =>
  createAsyncThunk<boolean, T>(
    route,
    async (args, {rejectWithValue, dispatch}) => {
      try {
        const res = await handler(args);
        return true;
      } catch (e: unknown) {
        return rejectWithValue('unknown');
      }
    }
  );

用法。

export const exportWorkload = getExportThunk<IServerGetWorkloadBody>(
  api.exportWorkload,
  'ytd/exportWorkload',
  'YTD Workload was successfully downloaded!'
);

但是,当我试图派遣getexportthunk的结果时,我会发现一个错误,上面写着:这是不确定的。在这种情况下如何通过上下文以及应该是哪个上下文?

错误堆栈: stacktrace

redux Promise Promise函数失败的位置

const promise = (async function () {
        let finalAction: ReturnType<typeof fulfilled | typeof rejected>
        try {
          let conditionResult = options?.condition?.(arg, { getState, extra })
          if (isThenable(conditionResult)) {
            conditionResult = await conditionResult
          }
          if (conditionResult === false) {
            // eslint-disable-next-line no-throw-literal
            throw {
              name: 'ConditionError',
              message: 'Aborted due to condition callback returning false.',
            }
          }
          started = true
          dispatch(
            pending(
              requestId,
              arg,
              options?.getPendingMeta?.({ requestId, arg }, { getState, extra })
            )
          )
//fails in this asignment
          finalAction = await Promise.race([
            abortedPromise,
            Promise.resolve(
              payloadCreator(arg, {
                dispatch,
                getState,
                extra,
                requestId,
                signal: abortController.signal,
                rejectWithValue: ((
                  value: RejectedValue,
                  meta?: RejectedMeta
                ) => {
                  return new RejectWithValue(value, meta)
                }) as any,
                fulfillWithValue: ((value: unknown, meta?: FulfilledMeta) => {
                  return new FulfillWithMeta(value, meta)
                }) as any,
              })
            ).then((result) => {
              if (result instanceof RejectWithValue) {
                throw result
              }
              if (result instanceof FulfillWithMeta) {
                return fulfilled(result.payload, requestId, arg, result.meta)
              }
              return fulfilled(result as any, requestId, arg)
            }),
          ])
        } catch (err) {
          finalAction =
            err instanceof RejectWithValue
              ? rejected(null, requestId, arg, err.payload, err.meta)
              : rejected(err as any, requestId, arg)
        }

I want to create createAsyncThunk function wrapper, because want to refactor 3 big thunks in one with parameters. Here my solution.

Code

export const getExportThunk = <T>(
  handler: (args: T) => Promise<boolean>,
  route: string,
  successText: string
) =>
  createAsyncThunk<boolean, T>(
    route,
    async (args, {rejectWithValue, dispatch}) => {
      try {
        const res = await handler(args);
        return true;
      } catch (e: unknown) {
        return rejectWithValue('unknown');
      }
    }
  );

Usage.

export const exportWorkload = getExportThunk<IServerGetWorkloadBody>(
  api.exportWorkload,
  'ytd/exportWorkload',
  'YTD Workload was successfully downloaded!'
);

But when I'm trying to dispatch the result of getExportThunk, I catch an error that says: this is undefined. How to pass context in this case and moreover which context it should be?

Error stacktrace:
stacktrace

Place where redux promise function fails

const promise = (async function () {
        let finalAction: ReturnType<typeof fulfilled | typeof rejected>
        try {
          let conditionResult = options?.condition?.(arg, { getState, extra })
          if (isThenable(conditionResult)) {
            conditionResult = await conditionResult
          }
          if (conditionResult === false) {
            // eslint-disable-next-line no-throw-literal
            throw {
              name: 'ConditionError',
              message: 'Aborted due to condition callback returning false.',
            }
          }
          started = true
          dispatch(
            pending(
              requestId,
              arg,
              options?.getPendingMeta?.({ requestId, arg }, { getState, extra })
            )
          )
//fails in this asignment
          finalAction = await Promise.race([
            abortedPromise,
            Promise.resolve(
              payloadCreator(arg, {
                dispatch,
                getState,
                extra,
                requestId,
                signal: abortController.signal,
                rejectWithValue: ((
                  value: RejectedValue,
                  meta?: RejectedMeta
                ) => {
                  return new RejectWithValue(value, meta)
                }) as any,
                fulfillWithValue: ((value: unknown, meta?: FulfilledMeta) => {
                  return new FulfillWithMeta(value, meta)
                }) as any,
              })
            ).then((result) => {
              if (result instanceof RejectWithValue) {
                throw result
              }
              if (result instanceof FulfillWithMeta) {
                return fulfilled(result.payload, requestId, arg, result.meta)
              }
              return fulfilled(result as any, requestId, arg)
            }),
          ])
        } catch (err) {
          finalAction =
            err instanceof RejectWithValue
              ? rejected(null, requestId, arg, err.payload, err.meta)
              : rejected(err as any, requestId, arg)
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌无敌 2025-02-08 12:31:33

正如@markerikson所说,问题是在API.exportworkload的上下文中,它在将其触发为Handler()并试图访问它后就失去了上下文。解决方案。

export const exportWorkload = getExportThunk<IServerGetWorkloadBody>(
  api.exportWorkload.bind(api),
  'ytd/exportWorkload',
  'YTD Workload was successfully downloaded!'
);

或使用箭头函数默认函数

  public exportWorkload = async (body: IServerGetWorkloadBody) => {
    const res = await this.ytdService.exportWorkload(body);

    return res;
  };

As @markerikson said, the problem was with context of api.exportWorkload, it was loosing its context after firing it as handler() and was trying to get access to it. The solution.

export const exportWorkload = getExportThunk<IServerGetWorkloadBody>(
  api.exportWorkload.bind(api),
  'ytd/exportWorkload',
  'YTD Workload was successfully downloaded!'
);

Or use arrow function instead default function

  public exportWorkload = async (body: IServerGetWorkloadBody) => {
    const res = await this.ytdService.exportWorkload(body);

    return res;
  };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文