2017-05-25 41 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")