即使 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,
};
}