Skip to content

Commit

Permalink
feat: useRequest support ready
Browse files Browse the repository at this point in the history
  • Loading branch information
zuofenghua committed Dec 9, 2021
1 parent a77ef4f commit c4b762e
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 53 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ahooks-vue",
"version": "0.12.3",
"version": "0.12.4",
"description": "ahooks-vue",
"types": "dist/src/index.d.ts",
"repository": "https://github.com/dewfall123/ahooks-vue.git",
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,3 @@ export * from './useThrottle';
export * from './useToggle';
export * from './useUrlState';
export * from './useWorkerFunction';

55 changes: 55 additions & 0 deletions src/useRequest/__test__/options.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,4 +282,59 @@ describe('useRequest - options', () => {
await sleep(100);
expect(loading.value).toEqual(true);
});

it('should ready work when manual = false', async () => {
const ready = ref(false);
const { loading } = useRequest(getFullName, {
ready,
manual: false,
});
expect(loading.value).toEqual(false);

await nextTickInFakeTimers();
ready.value = true;

await nextTickInFakeTimers();
expect(loading.value).toEqual(true);
});

it('should ready work when manual = false', async () => {
const ready = ref(true);
const { loading } = useRequest(getFullName, {
ready,
manual: false,
});
await nextTickInFakeTimers();
expect(loading.value).toEqual(true);
});

it('should ready work when manual = true', async () => {
const ready = ref(false);
const { loading, run } = useRequest(getFullName, {
ready,
manual: true,
});

expect(loading.value).toEqual(false);
run();
await nextTickInFakeTimers();
expect(loading.value).toEqual(false);

ready.value = true;
await nextTickInFakeTimers();
expect(loading.value).toEqual(false);

run();
await nextTickInFakeTimers();
expect(loading.value).toEqual(true);

jest.advanceTimersByTime(getFullNameTime);
await nextTickInFakeTimers();
expect(loading.value).toEqual(false);

ready.value = false;
run();
await nextTickInFakeTimers();
expect(loading.value).toEqual(false);
});
});
3 changes: 2 additions & 1 deletion src/useRequest/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ref } from 'vue-demi';
import { UseRequestOptions } from './types';

function fetchProxy(params: string | Record<string, string>) {
Expand Down Expand Up @@ -38,7 +39,7 @@ export const DefaultOptions = {
loadingWhenDebounceStart: true,
throttleInterval: 0,
initialData: undefined,
// ready: true,
ready: ref(true),
throwOnError: false,
refreshDeps: [],
refreshOnWindowFocus: false,
Expand Down
24 changes: 24 additions & 0 deletions src/useRequest/demo/demo-ready-manual-true.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<div>
<div>
<button @click="toggle()">toggle-ready</button>
<span style="margin-left: 8px;">ready: {{ ready }}</span>
</div>
<p>
UserName: <span>{{ loading ? 'loading' : data }}</span>
</p>
<button @click="run()">run</button>
</div>
</template>

<script lang="ts" setup>
import { useRequest, useToggle } from 'ahooks-vue';
import { getFullName } from './utils';
const { state: ready, toggle } = useToggle();
const { data, loading, run } = useRequest(getFullName, {
manual: true,
ready,
});
</script>
24 changes: 24 additions & 0 deletions src/useRequest/demo/demo-ready.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<div>
<div>
<button @click="toggle()">toggle-ready</button>
<span style="margin-left: 8px;">ready: {{ ready }}</span>
</div>
<p>
UserName: <span>{{ loading ? 'loading' : data }}</span>
</p>
<button @click="run()">run</button>
</div>
</template>

<script lang="ts" setup>
import { useRequest, useToggle } from 'ahooks-vue';
import { getFullName } from './utils';
const { state: ready, toggle } = useToggle();
const { data, loading, run } = useRequest(getFullName, {
manual: false,
ready,
});
</script>
53 changes: 35 additions & 18 deletions src/useRequest/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ The API is different from [ahooks](https://ahooks.js.org/hooks/async).
desc="Setting `options.loadingDelay` can specifies a delay in milliseconds for loading (prevent flush).">
</demo>

### Ready

<demo src="./demo/demo-ready.vue"
language="vue"
title="Ready"
desc="In the automatic mode of manual=false, every time ready changes from false to true, a request will be automatically executed with the parameter options.defaultParams">
</demo>

### Ready (manual = true)

<demo src="./demo/demo-ready-manual-true.vue"
language="vue"
title="Ready"
desc="When manual=true manual request mode, as long as ready=false, the request triggered by run will not be executed">
</demo>

## Basic API

```javascript
Expand Down Expand Up @@ -124,21 +140,22 @@ const {

All Options are optional.

| Property | Description | Type | Default |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------- | ------- |
| manual | <ul><li> The default `false`. That is, the service is automatically executed during initialization.</li><li>If set to `true`, you need to call `run` manually to trigger execution. </li></ul> | `boolean` | false |
| initialData | initial data | `any` | - |
| formatResult | Format request results | `(response: any) => any` | - |
| onSuccess | <ul><li> Triggered when the service resolved, the parameters are `data` and`params` </li><li> If `formatResult` is present,`data` is the formatted data.</li></ul> | `(data: any, params: any[]) => void` | - |
| onError | Triggered when the service reports an error. The parameters are `error` and`params`. | `(error: Error, params: any[]) => void` | - |
| defaultParams | If `manual = false`, the default parameters when run is executed automatically, | `any[]` | - |
| loadingDelay | Set delay time for display loading to avoid flicker | `number` | - |
| pollingInterval | Polling interval in milliseconds. After setting, it will enter polling mode and trigger `run` periodically. | `number` | - |
| pollingSinceLastFinished | <ul><li> Whether start next polling request since last request finished. Default is `true`. </li><li> If set `false`, request will start every `pollingInterval` time. </li></ul> | `boolean` | true |
| pollingWhenHidden | <ul><li> Whether to continue polling when the page is hidden. Default is `true`, that is, polling will not stop </li><li> If set to `false`, polling is temporarily stopped when the page is hidden, and the last polling is continued when the page is redisplayed </li></ul> | `boolean` | `true` |
| debounceInterval | debounce interval, the unit is millisecond. After setting, request to enter debounce mode. | `number` | - |
| loadingWhenDebounceStart | Whether set loading to `true` when the `run` function starts to execute. | `boolean` | `true` |
| throttleInterval | throttle interval, the unit is millisecond. After setting, request to enter throttle mode. | `number` | - |
| throwOnError | If the service errors, the error will only be logged. If you want an error to be thrown, pass the throwOnError: true | `boolean` | `false` |
| refreshOnWindowFocus `v0.9` | The request will be re-initiated when the screen is refocused or revisible. | `boolean` | `false` |
| refreshDeps `v0.9` | RefreshDeps changes will trigger the service to re-execute. | `WatchSource[]` | `[]` |
| Property | Description | Type | Default |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------- | ----------- |
| manual | <ul><li> The default `false`. That is, the service is automatically executed during initialization.</li><li>If set to `true`, you need to call `run` manually to trigger execution. </li></ul> | `boolean` | false |
| initialData | initial data | `any` | - |
| formatResult | Format request results | `(response: any) => any` | - |
| onSuccess | <ul><li> Triggered when the service resolved, the parameters are `data` and`params` </li><li> If `formatResult` is present,`data` is the formatted data.</li></ul> | `(data: any, params: any[]) => void` | - |
| onError | Triggered when the service reports an error. The parameters are `error` and`params`. | `(error: Error, params: any[]) => void` | - |
| defaultParams | If `manual = false`, the default parameters when run is executed automatically, | `any[]` | - |
| loadingDelay | Set delay time for display loading to avoid flicker | `number` | - |
| pollingInterval | Polling interval in milliseconds. After setting, it will enter polling mode and trigger `run` periodically. | `number` | - |
| pollingSinceLastFinished | <ul><li> Whether start next polling request since last request finished. Default is `true`. </li><li> If set `false`, request will start every `pollingInterval` time. </li></ul> | `boolean` | true |
| pollingWhenHidden | <ul><li> Whether to continue polling when the page is hidden. Default is `true`, that is, polling will not stop </li><li> If set to `false`, polling is temporarily stopped when the page is hidden, and the last polling is continued when the page is redisplayed </li></ul> | `boolean` | `true` |
| debounceInterval | debounce interval, the unit is millisecond. After setting, request to enter debounce mode. | `number` | - |
| loadingWhenDebounceStart | Whether set loading to `true` when the `run` function starts to execute. | `boolean` | `true` |
| throttleInterval | throttle interval, the unit is millisecond. After setting, request to enter throttle mode. | `number` | - |
| throwOnError | If the service errors, the error will only be logged. If you want an error to be thrown, pass the throwOnError: true | `boolean` | `false` |
| refreshOnWindowFocus `v0.9` | The request will be re-initiated when the screen is refocused or revisible. | `boolean` | `false` |
| refreshDeps `v0.9` | RefreshDeps changes will trigger the service to re-execute. | `WatchSource[]` | `[]` |
| ready `v0.12.4` | Is the current request ready | `Ref<Boolean>` | `ref(true)` |
26 changes: 21 additions & 5 deletions src/useRequest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function useRequest<R = any, P extends any[] = any>(
pollingSinceLastFinished,
refreshOnWindowFocus,
refreshDeps,
ready,
} = finalOptions;

let promiseService: (...args: P) => Promise<any>;
Expand Down Expand Up @@ -99,6 +100,10 @@ export function useRequest<R = any, P extends any[] = any>(
let pollingSinceFinishedTimer: any;

function _run(...args: P) {
// 只要 ready=false 不执行
if (!ready.value) {
return Promise.resolve();
}
if (pollingSinceFinishedTimer) {
clearTimeout(pollingSinceFinishedTimer);
}
Expand All @@ -118,11 +123,11 @@ export function useRequest<R = any, P extends any[] = any>(
params.value = cloneDeep(args);

// 抛弃该次请求结果
const shoundAbandon = () => unmountedFlag || curCount !== count;
const shouldAbandon = () => unmountedFlag || curCount !== count;

return promiseService(...args)
.then(res => {
if (shoundAbandon()) {
if (shouldAbandon()) {
return;
}
const formattedResult = formatResult(res);
Expand All @@ -133,7 +138,7 @@ export function useRequest<R = any, P extends any[] = any>(
return formattedResult;
})
.catch(err => {
if (shoundAbandon()) {
if (shouldAbandon()) {
return;
}
console.error(err);
Expand All @@ -144,7 +149,7 @@ export function useRequest<R = any, P extends any[] = any>(
}
})
.finally(() => {
if (shoundAbandon()) {
if (shouldAbandon()) {
return;
}
if (loadingDelayTimer) {
Expand Down Expand Up @@ -228,7 +233,18 @@ export function useRequest<R = any, P extends any[] = any>(

// 自动执行
if (!manual) {
run(...(defaultParams as P));
// ready 变为true 自动发起请求,会带上参数 options.defaultParams
watch(
ready,
() => {
if (ready.value) {
run(...(defaultParams as P));
}
},
{
immediate: true,
},
);
}

// refreshDeps
Expand Down
Loading

0 comments on commit c4b762e

Please sign in to comment.