EventLoop
监听事件:当任意WebSocket有可读数据,或exchange.Go()、HttpQuery_Go()等并发任务完成时返回。
EventLoop()
EventLoop(timeout)示例
并发获取行情、深度和成交记录,并使用EventLoop依次取回完成事件。
javascript
function main() {
var routine_getTicker = exchange.Go("GetTicker")
var routine_getDepth = exchange.Go("GetDepth")
var routine_getTrades = exchange.Go("GetTrades")
// 并发任务在提交时即已登记:即使这里先执行Sleep(2000),之后的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())
rust
fn main() {
// Rust 中 exchange.Go 使用类型化 token(如 Go::GetTicker)而非方法名字符串,无参数时传入 ()
let routine_getTicker = exchange.Go(Go::GetTicker, ());
let routine_getDepth = exchange.Go(Go::GetDepth, ());
let routine_getTrades = exchange.Go(Go::GetTrades, ());
// 并发任务在提交时即已登记:即使这里先执行Sleep(2000),之后的EventLoop也不会错过这些任务的完成事件
// Log!("GetDepth:", routine_getDepth.wait(0)) 如果在这里提前调用wait函数取出GetDepth并发调用的结果,
// 则此次GetDepth收到请求结果的事件不会再由EventLoop函数返回
let ts1 = Unix() * 1000;
let ret1 = EventLoop(0);
let ts2 = Unix() * 1000;
let ret2 = EventLoop(0);
let ts3 = Unix() * 1000;
let 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(0).unwrap());
Log!("GetDepth:", routine_getDepth.wait(0).unwrap());
Log!("GetTrades:", routine_getTrades.wait(0).unwrap());
}返回值
| 类型 | 描述 |
object | 事件对象,其中 |
参数
| 名称 | 类型 | 必填 | 描述 |
timeout | number | 否 | 超时时间(毫秒):为 |
参考
备注
exchange.Go()、HttpQuery_Go()等并发任务在提交时即已登记,即使任务在首次调用EventLoop()之前就已完成,也不会错过其完成事件。底层系统封装的队列结构每个线程最多缓存10240个事件,如果程序运行过程中未及时调用EventLoop()函数取出事件,超出上限时最早的事件会被丢弃。
EventLoop()函数的调用不会影响系统底层WebSocket的缓存队列,也不会影响exchange.Go()等并发函数的缓存,这些缓存中的数据仍需使用各自的方法取出。在EventLoop()函数返回之前已被取出的数据,不会再由EventLoop()函数产生返回事件。
EventLoop()函数的主要用途是通知策略层:系统底层已接收到新的网络数据,从而以事件驱动整个策略。当EventLoop()函数返回事件时,只需遍历所有数据来源,例如对WebSocket连接、exchange.Go()创建的对象尝试获取数据。
EventLoop()函数仅支持实盘。
在主函数main()中调用时,监听主线程的事件。在使用JavaScript语言编写的策略中,也可以在threading.Thread()函数所创建线程的执行函数中调用,此时监听当前线程的事件。
交易所的WebSocket推送通过ctx.subscribe订阅、通过ctx.poll取出;EventLoop()仅为柜台类(只提供推送接口)的交易所自动订阅当前交易对的行情和订单回报,不会为其他交易所订阅推送。在JavaScript、Rust中,同一线程内的EventLoop()与ctx.poll()从同一个事件队列获取事件,因此一个线程只应使用其中一种;Python的EventLoop()拥有独立的队列,与ctx.poll()互不争抢。