EventLoop

监听事件,在有任意WebSocket可读数据或者exchange.Go()HttpQuery_Go()等并发的任务完成以后返回。

返回的对象如果不为空值,则返回内容中包含的Event为事件触发类型。例如以下返回值结构:

{"Seq":1,"Event":"Exchange_GetTrades","ThreadId":0,"Index":3,"Nano":1682068771309583400}

object

EventLoop() EventLoop(timeout)

参数timeout为超时设置,单位为毫秒。 参数timeout如果设置为0则等待有事件发生才返回,如果大于0就是设置事件等待超时,小于0立即返回最近事件。 timeout false number

function main() {
    var routine_getTicker = exchange.Go("GetTicker")
    var routine_getDepth = exchange.Go("GetDepth")
    var routine_getTrades = exchange.Go("GetTrades")
    
    // Sleep(2000),如果这里使用Sleep语句,会导致之后的EventLoop函数错过之前的事件,因为等待了2秒,并发的函数已经收到了数据,后续才开始EventLoop监听机制,就错过了这些事件
    // 除非在第一行代码开始调用EventLoop(-1),首先初始化EventLoop的监听机制,则不会错过这些事件            

    // Log("GetDepth:", routine_getDepth.wait()) 如果这里提前调用wait函数取出GetDepth函数并发调用的结果,此次GetDepth函数收到请求结果的事件便不会在EventLoop函数返回
    var ts1 = new Date().getTime()
    var ret1 = EventLoop(0)
    
    var ts2 = new Date().getTime()
    var ret2 = EventLoop(0)
    
    var ts3 = new Date().getTime()
    var ret3 = EventLoop(0)
    
    Log("第1个并发任务完成的为:", _D(ts1), ret1)
    Log("第2个并发任务完成的为:", _D(ts2), ret2)
    Log("第3个并发任务完成的为:", _D(ts3), ret3)
    
    Log("GetTicker:", routine_getTicker.wait())
    Log("GetDepth:", routine_getDepth.wait())
    Log("GetTrades:", routine_getTrades.wait())
}
import time
def main():
    routine_getTicker = exchange.Go("GetTicker")
    routine_getDepth = exchange.Go("GetDepth")
    routine_getTrades = exchange.Go("GetTrades")
    
    ts1 = time.time()
    ret1 = EventLoop(0)
    
    ts2 = time.time()
    ret2 = EventLoop(0)
    
    ts3 = time.time()
    ret3 = EventLoop(0)
    
    Log("第1个并发任务完成的为:", _D(ts1), ret1)
    Log("第2个并发任务完成的为:", _D(ts2), ret2)
    Log("第3个并发任务完成的为:", _D(ts3), ret3)
    
    Log("GetTicker:", routine_getTicker.wait())
    Log("GetDepth:", routine_getDepth.wait())
    Log("GetTrades:", routine_getTrades.wait())
void main() {
    auto routine_getTicker = exchange.Go("GetTicker");
    auto routine_getDepth = exchange.Go("GetDepth");
    auto routine_getTrades = exchange.Go("GetTrades");
    
    auto ts1 = Unix() * 1000;
    auto ret1 = EventLoop(0);
    
    auto ts2 = Unix() * 1000;
    auto ret2 = EventLoop(0);
    
    auto ts3 = Unix() * 1000;
    auto ret3 = EventLoop(0);
    
    Log("第1个并发任务完成的为:", _D(ts1), ret1);
    Log("第2个并发任务完成的为:", _D(ts2), ret2);
    Log("第3个并发任务完成的为:", _D(ts3), ret3);
    
    Ticker ticker;
    Depth depth;
    Trades trades;
    routine_getTicker.wait(ticker);
    routine_getDepth.wait(depth);
    routine_getTrades.wait(trades);
    
    Log("GetTicker:", ticker);
    Log("GetDepth:", depth);
    Log("GetTrades:", trades);
}

代码中第一次调用EventLoop()函数才会初始化该监听事件的机制,如果在事件回调之后才开始首次EventLoop()调用,会错过之前的事件。 底层系统封装的队列结构会缓存最大500个事件回调,如果程序执行过程中没有及时调用EventLoop()函数取出,会丢失500个缓存之外较晚的事件回调。 EventLoop()函数的调用不会影响系统底层WebSocket的缓存队列,也不影响exchange.Go()等并发函数的缓存, 对于这些缓存依然需要使用各自的方法取出数据。对于在EventLoop()函数返回之前,已经取出的数据,不会在EventLoop()函数中产生返回事件。 EventLoop()函数的主要用途就是通知策略层,系统底层接收到了新的网络数据。以事件驱动整个策略。当EventLoop()函数返回事件时, 只需遍历所有数据来源。例如WebSocket连接、exchange.Go()创建的对象尝试获取数据。 EventLoop()函数仅支持实盘。 在主函数main()中调用时,监听主线程的事件。 在JavaScript语言编写的策略中,threading.Thread()函数创建的线程,在线程的执行函数中也可以调用,监听当前线程的事件。

{@fun/Global/Dial Dial}, {@fun/Trade/exchange.Go exchange.Go}, {@fun/Global/HttpQuery_Go HttpQuery_Go}