Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangfisher committed Jun 30, 2024
1 parent ce5e1e1 commit c453879
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 14 deletions.
86 changes: 85 additions & 1 deletion packages/reactive/src/__tests__/async/funcs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/


import { test,expect, describe, beforeAll } from "vitest"
import { test,expect, describe, beforeAll, vi } from "vitest"
import { createStore,ComputedScopeRef,computed, IStore } from "../.."
import { delay } from "flex-tools/async/delay"

Expand Down Expand Up @@ -43,6 +43,90 @@ describe("异步计算控制功能",()=>{
})
store.state.total
})
})


test("通过abortSignal来中止计算函数的执行",()=>{
return new Promise<void>((resolve)=>{
const fn = vi.fn()
const store = createStore({
price:2,
count:3,
total:computed(async (scope,{abortSignal})=>{
return new Promise<number>((resolve,reject)=>{
// 当接收到中止信号时,必须主动reject或者resolve,否则会被视为正常执行
abortSignal.addEventListener("abort",()=>{
fn()
reject("cancelled")
})
// 模拟一个耗时的异步操作
setTimeout(()=>{
resolve(scope.count*scope.price)
},10 *1000)

})
},['price','count'],{id:'x'})
})
store.on("computed:cancel",({reason})=>{
expect(reason).toBe("abort")
expect(fn).toHaveBeenCalled()
resolve()
})
store.on("computed:created",()=>{
setTimeout(()=>{
store.computedObjects.get("x")!.cancel()
})
})
store.state.total
})
})

test("当执行计算函数出错时,自动重试5次",()=>{
let count = 0
return new Promise<void>((resolve)=>{
const store = createStore({
price:2,
count:3,
total:computed(async (scope,{})=>{
count++
if(count===6){ // 第一次执行失败,然后重试5次,共执行6次
resolve()
}else{
throw new Error("error")
}
return scope.price * scope.count
},['price','count'],{id:'x',retry:5})
})
store.state.total
})
})
test("当执行计算函数出错时自动重试5次并且指定重试间隔",()=>{
let count = 0
let times:number[] = []
return new Promise<void>((resolve)=>{
const store = createStore({
price:2,
count:3,
total:computed(async (scope,{})=>{
times.push(Date.now())
count++
if(count===6){
times.forEach((time,index)=>{
if(index>0){
expect(time-times[index-1]).toBeGreaterThanOrEqual(100)
}
})
resolve()
}else{
throw new Error("error")
}
return scope.price * scope.count
},['price','count'],{id:'x',retry:[5,100]})
})
store.state.total
})
})



})
9 changes: 6 additions & 3 deletions packages/reactive/src/computed/async.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ async function executeComputedGetter<T extends StoreDefine>(draft:any,computedRu
updateAsyncComputedState(setState,resultPath,{loading:true,error:null,retry:i>0 ? retryCount- i : 0,timeout:countdown > 1 ? countdown :timeoutValue,progress:0})
// 如果有中止信号,则取消计算
if(hasAbort){
throw new Error('Aborted')
throw new Error("Abort")
}
// 超时处理
if(timeoutValue>0){
Expand All @@ -133,11 +133,12 @@ async function executeComputedGetter<T extends StoreDefine>(draft:any,computedRu
}
// 执行计算函数
computedResult = await getter.call(thisDraft, scopeDraft,computedParams);
if(hasAbort) throw new Error("Abort")
if(!isTimeout){
Object.assign(afterUpdated,{result:computedResult,error:null,timeout:0})
}
}catch (e:any) {
hasError = e
hasError = true
if(!isTimeout){
Object.assign(afterUpdated,{error:getError(e).message,timeout:0})
}
Expand All @@ -164,7 +165,9 @@ async function executeComputedGetter<T extends StoreDefine>(draft:any,computedRu
}
}
// 计算完成后触发事件
if(hasError){
if(hasAbort){
store.emit("computed:cancel",{path:valuePath,id,reason:'abort'})
}else if(hasError){
store.emit("computed:error",{path:valuePath,id,error:hasError})
}else{
store.emit("computed:done",{path:valuePath,id,value:computedResult})
Expand Down
12 changes: 6 additions & 6 deletions packages/reactive/src/computed/computedObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { ComputedOptions, RuntimeComputedOptions } from "./types"

export class ComputedObject<T extends Dict = Dict,R=any> {
options:Required<ComputedOptions>
private _value:any
constructor(public store:IStore<T>,public selfReactiveable:Reactiveable<any> | undefined,public path:string[],options:ComputedOptions){
this.options = Object.assign({
},options) as Required<ComputedOptions>
Expand All @@ -18,16 +17,17 @@ export class ComputedObject<T extends Dict = Dict,R=any> {
get async(){return this.options.async}
get depends(){return this.options.depends}
get value(){
//if(this._value===undefined){
return this._value = getVal(this.selfReactiveable ? this.selfReactiveable?.state : this.store.state,this.path)
//}
//return this._value as R
return getVal(this.selfReactiveable ? this.selfReactiveable?.state : this.store.state,this.path)
}
run(options?:RuntimeComputedOptions) {
return this.store.reactiveable?.runComputed(this.id,options)
}
cancel(){

if(this.async){
this.value.cancel()
}else{
throw new Error("cancel only works for async computed")
}
}

}
Expand Down
5 changes: 1 addition & 4 deletions packages/reactive/src/computed/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { switchValue } from "flex-tools/misc/switchValue";
import { OBJECT_PATH_DELIMITER } from "../consts";
import { IReactiveReadHookParams } from "../reactives/types";
import { AsyncComputedObject, ComputedOptions, ComputedScopeRef, Dict, IStore } from "../types";
import { getComputedId, skipComputed } from "../utils";
import { skipComputed } from "../utils";



Expand Down

0 comments on commit c453879

Please sign in to comment.