§ Fox3.0前端框架-EventChain


§ 1.事件链路

fox.EventChain fox框架提供了一个可以让异步事件按顺序执行的工具类

定义 let eventchain = new fox.Event(session, persistentMode = false)

构造函数参数说明

参数 类型 说明
session Object 链接执行会话,可以保存链路执行共享数据
persistentMode Boolean 默认为false,非持久状态,true为持久状态

非持久状态,适用大多数情况,在此状态下任务执行后,即给丢弃,队列光标只能前进而不能后退 持久状态,任务执行还会给保存下来,可以用循环,回退等复杂操作

API

方法说明

方法 说明
post 把待执行数据加入事件链路
wait 加入链路的成功、失败处理函数

§ 1.1 post 加入任务

post((context)=>{
   context.resolve()
})

§ 1.2 wait 加入处理函数

 wait(()>{
 console.info("成功处理")
 },()=>{
 console.error("失败处理")
 })

§ 2.普通用法

let chain = new fox.EventChain()
//加入任务
chain.post((context)=>{
    setTimeout(()=>{
        console.info("a步骤1")
        //触发下一个步骤
        context.resolve()
    },2000)
}).post((context)=>{
    //处理本步骤
    console.info("a步骤2")
    //触发下一个步骤
    context.resolve()
}).post((context)=>{
    console.info("a步骤3")
    //触发下一个步骤
    context.resolve("ok")
}).wait((cotnext, res)=>{
    console.info("a步骤成功:"+res)
},(context,error)=>{
    console.info("a步骤失败:"+error)
})

以上代码执行顺序如下:

  1. a步骤1
  2. a步骤2
  3. a步骤3
  4. a步骤成功:ok

§ 3.任务中加入子任务

在任务中可以加入子任务,通过链路中上下文context的insert函数加入,切记必须在context的resolve方法调用前加入子任务,如下

//创建event chain
let chain = new fox.EventChain()
//加入任务
chain.post((context)=>{
    setTimeout(()=>{
        console.info("b步骤1")
        //触发下一个步骤
        context.resolve()
    },2000)
}).post((context)=>{

    //在步骤2之后插入子步骤2-1(必须在resolve之前加入)
    context.insert((step)=>{
        console.info("b步骤2-1")
        //触发下一个步骤
        step.resolve()
    })

    //在步骤2之后插入子步骤2-2(必须在resolve之前加入)
    context.insert((step)=>{
        setTimeout(()=>{
            console.info("b步骤2-2")
            //触发下一个步骤
            step.resolve()
        },100)
    })

    //处理本步骤
    console.info("b步骤2")
    //触发下一个步骤
    context.resolve()

}).post((context)=>{
    console.info("b步骤3")
    //触发下一个步骤
    context.resolve()
}).wait((context)=>{
    console.info("b步骤成功")
},(context)=>{
    console.info("b步骤失败")
})

以上代码的调用顺序为:

  1. b步骤1
  2. b步骤2
  3. b步骤2-1
  4. b步骤2-2
  5. b步骤3
  6. b步骤成功

§ 4.中断任务链路

在任务中可以通过context.reject方法中断任务的执行,任务失败后,直接触发wait函数中的失败处理函数,代码如下

//创建event chain
let chain = new fox.EventChain()
//加入任务
chain.post((context)=>{
    setTimeout(()=>{
        console.info("c步骤1")
        //触发下一个步骤
        context.resolve()
    },4000)
}).post((context)=>{

    //在步骤2之后插入子步骤2-1(必须在resolve之前加入)
    context.insert((step)=>{
        console.info("c步骤2-1")
        //触发下一个步骤
        step.reject("over")
    })

    //在步骤2之后插入子步骤2-2(必须在resolve之前加入)
    context.insert((step)=>{
        setTimeout(()=>{
            console.info("c步骤2-2")
            //触发下一个步骤
            step.resolve()
        },100)
    })

    //处理本步骤
    console.info("c步骤2")
    //触发下一个步骤
    context.resolve()

}).post((context)=>{
    console.info("c步骤3")
    //触发下一个步骤
    context.resolve("ok")
}).wait((context, res)=>{
    console.info("c步骤成功:"+res)
},(context, error)=>{
    console.info("c步骤失败:"+error)
})

以上代码的执行顺序如下

  1. c步骤1
  2. c步骤2
  3. c步骤2-1
  4. c步骤失败:over

§ 5.高级用法

§ 5.1 EventChain状态

let eventchain = new fox.Event(session, persistentMode = false)

EventChain有两种形式

  • 普通状态
  • 持久状态

在普通状态下,任务执行后就会被丢弃,也就是我们直接最event chain执行跳过任务操作,而不能循环或回退,普通状态event chain的定义方式如下:

//无参数方式(普通状态)
let chain = new fox.EventChain()

//带session方式(普通状态)
let session = {
    id:'007',
    name:'江成'
}
let chain = new fox.EventChain(session)


//带session方式,并显式设置非持久状态(普通状态)
let session = {
    id:'007',
    name:'江成'
}
let chain = new fox.EventChain(session, false)

在持久状态下,任务执行后会给保存下来,后续我们通过go函数对队列执行跳过任务、或循环执行同一任务,或回退到某个节点重新执行,持久状态定义方式如下:

//无session方式,并显式设置非持久状态(持久状态)
 let chain = new fox.EventChain(undefined, true)
 
//带session方式,并显式设置非持久状态(持久状态)
let session = {
    id:'007',
    name:'江成'
}
let chain = new fox.EventChain(session, true)

§ 5.2 Skip操作

根据某种条件,跳过队列中的某个任务 skip.png-8.9kB

代码

let needCheck = true
let chain = new fox.EventChain({}, true)
chain.post((context)=>{
    setTimeout(()=>{
        console.info("a.setCheckCondition")
        context.resolve(['a', 'b', 'c'])
    },10)
}).post((context, ...args)=>{
    setTimeout(()=>{
        console.info("a.check input:"+(JSON.stringify(args)))
        context.resolve()
    },20)
}).post((context, ...args)=>{
    console.info("a.preSubmit input:"+(JSON.stringify(args)))
    context.resolve("pre check ok")
}).post((context, ...args)=>{
    setTimeout(()=>{
        console.info("a.commit input:"+(JSON.stringify(args)))
        if(needCheck){
            context.go(2,"need check")
        }else{
            context.resolve("not need check")
        }
    },5)
}).post((context, ...args)=>{
    setTimeout(()=>{
        console.info("a.submit input:"+(JSON.stringify(args)))
        context.resolve("submit ok")
    },5)
}).wait((context, ...args)=>{
    setTimeout(()=>{
        console.info("a.postSubmit input:"+(JSON.stringify(args)))
    },5)
})

执行结果

a.setCheckCondition
a.check input:[["a","b","c"]]
a.preSubmit input:[]
a.commit input:["pre check ok"]
a.postSubmit input:["need check"]

§ 5.3 Loop操作

根据条件,循环执行某一个任务节点 loop.png-8.4kB

代码

let n = 3;

//创建event chain
let chain = new fox.EventChain({time:0}, true)
chain.post((context)=>{
    console.info("步骤1")
    context.resolve()
}).post((context)=>{
    console.info("步骤2")
    context.resolve()
}).post((context)=>{
    if(context.session.time < n){
        console.info("步骤3, loop time:"+context.session.time)
        context.session.time = context.session.time+1
        //循环
        context.go(0)
    }else{
        setTimeout(()=>{
            context.go(1)
        },200)
    }
}).post((context)=>{
    console.info("步骤4")
    context.resolve()
}).wait((success)=>{
    console.info("ok")
})

执行结果

步骤1
步骤2
步骤3, loop time:0
步骤3, loop time:1
步骤3, loop time:2
步骤4
ok

§ 5.4 Retry操作

通过go(-n)操作可以回退到某一个节点,重新开始执行 back.png-8.4kB

代码

//创建event chain
let chain = new fox.EventChain({flag:true}, true)
chain.post((context)=>{
    console.info("步骤1")
    context.resolve()
}).post((context)=>{
    setTimeout(()=>{
        console.info("步骤2")
        context.resolve()
    },100)
}).post((context)=>{
    if(context.session.flag){
        context.session.flag =false
        console.info("步骤3, 回退到步骤1")
        //循环
        context.go(-2)
    }else{
        setTimeout(()=>{
            console.info("步骤3, 跳转到步骤4")
            context.go(1)
        },200)
    }
}).post((context)=>{
    console.info("步骤4")
    context.resolve()
}).wait((success)=>{
    console.info("ok")
})

执行结果

步骤1
步骤2
步骤3, 回退到步骤1
步骤1
步骤2
步骤3, 跳转到步骤4
步骤4
ok
最后更新于: 7/5/2022, 5:29:52 PM