Created
May 5, 2019 22:48
-
-
Save CreatCodeBuild/3d46fc895ea5debbc7b3ddf92a52890d to your computer and use it in GitHub Desktop.
Why "Generator is already running"? I need help!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const EventEmitter = require('events'); | |
class MyEmitter extends EventEmitter { } | |
let e = new MyEmitter() | |
const DriveMainLoop = Symbol("DriveMainLoop"); | |
// eventBus must be the kernel/task this sleeper belongs to | |
function Sleeper(eventBus, doneToken) { | |
return { | |
Sleep: function (time) { | |
setTimeout(function () { | |
eventBus.emit(doneToken) | |
}, time); | |
}, | |
} | |
} | |
function Task(e, gf) { | |
const advanceToken = Symbol("advanceToken"); | |
const doneToken = Symbol("doneToken"); | |
let ret; | |
let done; | |
let task = { | |
join: function () { | |
if (done) { | |
done = false; | |
e.emit(doneToken, ret) // ???? TypeError: Generator is already running | |
return | |
} | |
e.on("task return", (data)=> { | |
done = false; | |
e.emit(DriveMainLoop, data) | |
}) | |
}, // should return a future with a resolve as a callback | |
Sleep: Sleeper(e, advanceToken).Sleep, | |
advanceToken: advanceToken, | |
doneToken: doneToken, | |
setResult: function(result) { | |
e.emit("task return", result) | |
done = true | |
ret = result | |
} | |
} | |
let g = gf(task) | |
task.next = function(data) { | |
return g.next(data) | |
} | |
return task | |
} | |
function Kernel() { | |
let mainTask; | |
return { | |
Go: function (gf) { | |
let t = Task(e, gf); | |
e.on(t.doneToken, (data)=>{ | |
mainTask.next(data); | |
}); | |
e.on(t.advanceToken, (data)=> { | |
try { | |
let step = t.next(data); | |
if (step.done) { | |
t.setResult(step.value) | |
} | |
} catch (e) { | |
console.log("task err", e) | |
} | |
}); | |
e.emit(t.advanceToken) | |
return t | |
}, | |
Run: function (gf) { | |
mainTask = gf(); | |
let g = mainTask; | |
e.on(DriveMainLoop, (data) => { | |
try { | |
let mainLoopResult = g.next(data); | |
} catch (e) { | |
console.log("main err", e) | |
} | |
}); | |
e.emit(DriveMainLoop); | |
}, | |
Sleep: Sleeper(e, DriveMainLoop).Sleep, | |
} | |
} | |
let kernel = Kernel(); | |
kernel.Run(function* () { | |
let task = kernel.Go(function* (t) { | |
for (let i = 0; i < 2; i++) { | |
yield t.Sleep(200) | |
console.log("child job slept", i) | |
} | |
return "child job done!" | |
}) | |
for (let i = 0; i < 5; i++) { | |
yield kernel.Sleep(200) | |
console.log("slept", i) | |
} | |
console.log("after for loop") | |
console.log("main loop", yield task.join()) // print child job done | |
}); | |
console.log("blocked?"); // kernel Run does not block. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
L58
Ref: