目的
既存のコードでcoを用いたgenerator/yeildを使っていたが、
co自体がもう更新されなくなってきているためにasync/awaitに置き換えることになった。
作業中両者が混在することになるが、
その時どのような振る舞いをするかわからなかったので試した。
結論
asyncをyieldで待つことは可能
generatorをawaitで待つことは不可能
実行環境
- Windows 10
- Node.js 10.15.3
- TypeScript 3.4.1?
- co 4.6.0
コード
5秒間待つ処理をするPromiseをgeneratorとasyncで覆って、
それぞれをyield、awaitで待つ4通りを試す。
長いので折り畳み
const co = require('co');
const waitTime = 5000;
function execute() {
generator_yield();
async_await();
async_yield();
generator_await();
}
execute();
function generator_yield() {
co(function* () {
let result = yield generatorFunction('generator_yield');
console.log(result);
});
}
function async_await(){
(async() => {
let result = await asyncFunction('async_await');
console.log(result);
})();
}
function async_yield() {
co(function* () {
let result = yield asyncFunction('async_yield');
console.log(result);
});
}
function generator_await() {
(async () => {
let result = await generatorFunction('generator_await');
console.log(result);
})();
}
function* generatorFunction(callee: string){
return timer(callee);
}
async function asyncFunction(callee: string) {
return timer(callee);;
}
function timer(callee: string){
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(callee);
}, waitTime);
});
}
結果
// generator/awaitの組み合わせだけ、5秒待たずに即座に表示される
{ next: [Function],
throw: [Function],
return: [Function],
[Symbol(Symbol.iterator)]: [Function] }
// 5秒待ってから表示される
generator_yield
async_yield
async_await
結論
asyncをyieldで待つことは可能
generatorをawaitで待つことは不可能
そのためgenerator/yeildからasync/awaitに置き換えるときは、
呼び出される関数から先にasync/awaitに置き換えていく必要がある。
感想
そもそもgeneratorとは何なのかふんわりとしか把握していないのが怖い。