监听事件,当有任意 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
”`javascript 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("First concurrent task completed:", _D(ts1), ret1)
Log("Second concurrent task completed:", _D(ts2), ret2)
Log("Third concurrent task completed:", _D(ts3), ret3)
Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())
}
python
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("First concurrent task completed:", _D(ts1), ret1)
Log("Second concurrent task completed:", _D(ts2), ret2)
Log("Third concurrent task completed:", _D(ts3), ret3)
Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())```
”`cpp 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("First concurrent task completed:", _D(ts1), ret1);
Log("Second concurrent task completed:", _D(ts2), ret2);
Log("Third concurrent task completed:", _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}