1

即使 Promise 没有结束,下面的“状态”也会发出两次。好吧,我知道每个参数(成功数据,加载,错误)分别很好。但是每当我合并它们时,就会出现错误。

import { computed, reactive, toRefs, watch, ref } from '@vue/composition-api';
import { Data } from '@vue/composition-api/dist/component';

export default function usePromise(fn: any) {
  if (!fn) {
    throw new Error(`[usePromise]: 1st argument is required (must be a function)`);
  }

  if (typeof fn !== 'function') {
    throw new TypeError(`[usePromise]: argument has to be function, but received ${typeof fn}`);
  }
  const state: any = reactive({
    successData: {},
    loading: true,
    errored: false,
    errorMessage: '',
    errorCode: 0,
    end: false,
  });

  let lastPromise;
  const use = async (...args: any) => {
    state.loading = true;
    const promise = (lastPromise = fn(...args));
    try {
      const result = await promise;
      if (lastPromise === promise) {
        state.successData = result.data;
        state.errored = false;
      }
    } catch (error) {
      if (!error.response) {
        state.errorCode = 900;
        state.errorMessage = 'Network Error';
      }
      state.errorMessage = error.response.data.error;
      state.errorCode = error.response.status;

      state.errored = true;
    } finally {
      state.loading = false;
      state.end = true;
    }
  };

  const responsePayload = computed(() => {
      return state;
  });
  return {
    responsePayload,
    use,
  };
}



我再次尝试导致错误。

  const responsePayload = computed(() => {
    if (state.end === true) {
      return state;
    }
  });
 Invalid watch source: undefined.
      A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these type

这种事情也是不允许的。我只希望只有在承诺结束时才发出一次 responsePayload

  const state: any = reactive({
    responsePayload : {
      successData: {},
      loading: true,
      errored: false,
      errorMessage: '',
      errorCode: 0,
      end: false,
    }
  });

像 Object.assign.. 这样的方法不起作用。我别无选择,只能像这样分别引用所有数据。

function useUpdateResetToken(axios) {
  const { successData, errored, errorMessage, errorCode, loading, use: create } = usePromiseFn((toAddress) =>
    axios.post('/api/v1/admin/users/updateResetToken', { toAddress }),
  );
  const updateResetToken = (toAddress) => {
    return create(toAddress);
  };
  return { updateResetToken, successData, errored, errorMessage, errorCode, loading };
}

[更新] 这有效,但发出未定义。

import { computed, reactive, toRefs, watch, ref } from '@vue/composition-api';
import { Data } from '@vue/composition-api/dist/component';

interface PromiseFields {
  successData: any;
  loading: boolean;
  errored: boolean;
  errorMessage: string;
  errorCode: number;
}

export default function usePromise(fn: any) {
  if (!fn) {
    throw new Error(`[usePromise]: 1st argument is required (must be a function)`);
  }

  if (typeof fn !== 'function') {
    throw new TypeError(`[usePromise]: argument has to be function, but received ${typeof fn}`);
  }

  const _loading = ref(false);
  const state: any = reactive({
    successData: {},
    loading: computed(() => _loading.value),
    errored: false,
    errorMessage: '',
    errorCode: 0,
  });

  let lastPromise;
  const use = async (...args: any) => {
    _loading.value = true;
    const promise = (lastPromise = fn(...args));
    try {
      const result = await promise;
      if (lastPromise === promise) {
        state.successData = result.data;
        state.errored = false;
      }
    } catch (error) {
      if (!error.response) {
        state.errorCode = 900;
        state.errorMessage = 'Network Error';
      }
      state.errorMessage = error.response.data.error;
      state.errorCode = error.response.status;

      state.errored = true;
    } finally {
      _loading.value = false;
    }
  };

  const responsePayload = computed(() => {
    if (_loading.value === false) {
      return state;
    } else {
      return undefined;
    }
  });
  return {
    responsePayload,
    use,
  };
}



4

0 回答 0