مقداری حکمت عملی کو نافذ کرتے وقت ، بیک وقت عملدرآمد بہت سے معاملات میں تاخیر کو کم کرسکتا ہے اور کارکردگی کو بہتر بنا سکتا ہے۔ ہیجنگ روبوٹ کو بطور مثال لیتے ہوئے ، ہمیں دو سکے کی گہرائی حاصل کرنے کی ضرورت ہے۔ ترتیب میں عملدرآمد کا کوڈ مندرجہ ذیل ہے:
var depthA = exchanges[0].GetDepth()
var depthB = exchanges[1].GetDepth()
ریست API کی درخواست میں تاخیر ہے۔ فرض کریں کہ یہ 100ms ہے ، گہرائی حاصل کرنے کا وقت دراصل مختلف ہے۔ اگر زیادہ رسائی کی ضرورت ہو تو ، تاخیر کا مسئلہ زیادہ نمایاں ہوجائے گا اور حکمت عملی کے نفاذ کو متاثر کرے گا۔
جاوا اسکرپٹ میں ملٹی تھریڈنگ نہیں ہے ، لہذا اس مسئلے کو حل کرنے کے لئے گو فنکشن کو نچلے حصے میں احاطہ کیا گیا ہے۔ تاہم ، ڈیزائن میکانزم کی وجہ سے ، اس پر عمل درآمد نسبتا cumbersome مشکل ہے۔
var a = exchanges[0].Go("GetDepth")
var b = exchanges[1].Go("GetDepth")
var depthA = a.wait() // Call the wait method to wait for the return of the depth result asynchronously
var depthB = b.wait()
زیادہ تر آسان معاملات میں ، اس طرح حکمت عملی لکھنے میں کوئی حرج نہیں ہے۔ تاہم ، یہ نوٹ کیا گیا ہے کہ اس عمل کو ہر حکمت عملی لوپ کے لئے دہرانا چاہئے۔ انٹرمیڈیٹ متغیر a اور b صرف عارضی امداد ہیں۔ اگر ہمارے پاس بہت سارے متوازی کام ہیں تو ، ہمیں a اور depthA ، اور b اور depthB کے مابین متعلقہ تعلقات کو ریکارڈ کرنے کی ضرورت ہے۔ جب ہمارے متوازی کام غیر یقینی ہوتے ہیں تو ، صورتحال زیادہ پیچیدہ ہوجاتی ہے۔ لہذا ، ہم ایک فنکشن کو نافذ کرنا چاہتے ہیں: جب متوازی طور پر جائیں ، متغیر کو ایک ہی وقت میں پابند کریں ، اور جب متوازی آپریشن کا نتیجہ لوٹتا ہے تو ، نتیجہ خود بخود متغیر کو تفویض کیا جائے گا ، اس طرح انٹرمیڈیٹ متغیر کو ختم کرکے اور پروگرام کو زیادہ جامع بناتا ہے۔ اس طرح کی مخصوص عمل درآمد مندرجہ ذیل ہے:
function G(t, ctx, f) {
return {run:function(){
f(t.wait(1000), ctx)
}}
}
ہم ایک G فنکشن کی وضاحت کرتے ہیں، جہاں پیرامیٹر t چلنے والا Go فنکشن ہے، ctx ریکارڈنگ پروگرام کا سیاق و سباق ہے، اور f مخصوص تفویض فنکشن ہے۔ آپ بعد میں فنکشن دیکھیں گے۔
اس وقت ، مجموعی طور پر پروگرام فریم ورک کو
var Info = [{depth:null, account:null}, {depth:null, account:null}] // If we need to obtain the depth and account of the two exchanges, more information can also be put in, such as order ID, status, etc.
var tasks = [ ] // Global list of tasks
function produce(){ // Issue various concurrent tasks
// The logic of task generation is omitted here, for demonstration purposes only.
tasks.push({exchange:0, ret:'depth', param:['GetDepth']})
tasks.push({exchange:1, ret:'depth', param:['GetDepth']})
tasks.push({exchange:0, ret:'sellID', param:['Buy', Info[0].depth.Asks[0].Price, 10]})
tasks.push({exchange:1, ret:'buyID', param:['Sell', Info[1].depth.Bids[0].Price, 10]})
}
function worker(){
var jobs = []
for(var i=0;i<tasks.length;i++){
var task = tasks[i]
tasks.splice(i,1) // Delete executed tasks
jobs.push(G(exchanges[task.exchange].Go.apply(this, task.param), task, function(v, task) {
Info[task.exchange][task.ret] = v // The v here is the return value of the concurrent Go function wait(), which can be experienced carefully.
}))
}
_.each(jobs, function(t){
t.run() // Execute all tasks concurrently here
})
}
function main() {
while(true){
produce() // Send trade orders
worker() // Concurrent execution
Sleep(1000)
}
}
ایسا لگتا ہے کہ حلقوں میں گھومنے کے بعد صرف ایک سادہ فنکشن کو نافذ کیا گیا ہے۔ در حقیقت ، کوڈ کی پیچیدگی کو بہت آسان بنا دیا گیا ہے۔ ہمیں صرف اس بات کی پرواہ کرنے کی ضرورت ہے کہ پروگرام کو کون سے کاموں کو پیدا کرنے کی ضرورت ہے۔ ورکر ((() پروگرام خود بخود انہیں بیک وقت انجام دے گا اور اسی کے نتائج واپس کرے گا۔ لچک بہت بہتر ہوگئی ہے۔