2017-05-25 81 views
0

我需要做一些CPU繁重的計算插座服務器節點之間執行,但我不希望阻止我的IO。允許IO和定時器重計算

是否可以使用ES6/ES7特徵很好的方式來實現這一目標。

我第一次嘗試是使用異步和等待,但看起來,如果重同步功能之前計時器事件調用,計時器事件被稱爲只有在所有繁重的計算調用執行。 https://jsfiddle.net/bz31vk97/1/

let t = 0 
setInterval(async function() { 
    t = t + 1 
    console.log("timer: ", t) 
}, 1000) 

async function syncDelay(ms) { 
    console.log("syncDelay: ", ms, "ms") 
    let t1 = Date.now() 
    while (Date.now() - t1 < ms) {} 
    return ms 
} 

async function heavyWork() { 
    for (let i = 0; i < 10; i++) { 
    await syncDelay(500) 
    } 
} 

heavyWork() 
console.log("after calling heavyWork") 

同樣的,當我更換等待着setImmediate節點撥打:

setImmediate(() => syncDelay(500)) 

兩個版本首先調用所有syncDelays,然後纔開始通話計時事件。

有沒有什麼辦法可以讓IO和定時器事件的幾個CPU重來電之間叫什麼名字?

+0

'async' /'await'僅供*異步*繁重的工作好。你甚至沒有在一個真正的異步任務完成後履行的承諾。而所有的[承諾回調優先區間回調(https://stackoverflow.com/q/42800326/1048572)。 – Bergi

回答

0

一個我想出瞭解決方案的是使保持在隊列中的作品和以前結束後,增加了未來工作的JavaScript事件循環一的WorkManager。這樣,其他事件可以在CPU繁重的工作負載部件之間存在。

https://jsfiddle.net/bz31vk97/2

let t = 0 
setInterval(async function() { 
    t = t + 1 
    console.log("timer: ", t) 
}, 1000) 

async function syncDelay(ms) { 
    console.log("syncDelay: ", ms, "ms") 
    let t1 = Date.now() 
    while (Date.now() - t1 < ms) {} 
    return ms 
} 

class WorkManager { 
    addWork(work) { 
    if (this.first === undefined) { 
     this.first = work 
     this.last = work 
     this.runWork() 
    } else { 
     this.last.next = work 
     this.last = work 
    } 
    } 
    newWork(fn, ...args) { 
    this.addWork({fn, args}) 
    } 
    runWork() { 
    let work = this.first 
    if (this.first === undefined) { 
     return 
    } 
    setTimeout(() => { 
     this.first = this.first.next 
     work.fn(...work.args) 
     this.runWork() 
    }, 0) 
    } 
} 

let wm = new WorkManager() 
for (let i = 0; i < 10; i++) { 
    wm.newWork(syncDelay, 500) 
} 

console.log("after calling heavyWork")