◆ await すると then メソッドが実行される
◆ 変わった関数実行方法なので面白い使いみちありそうだけど思いつかない
◆ async 関数の返り値にしても then メソッドが実行される
◆ こっちは then を実行してほしいときに then を自分で書いたり await しなくてもいいので普通に便利そう

await と thenable オブジェクト

await では内部的に then を呼び出します
なのでこんなことができます

const async_counter = { count: 0, then(a, b) { return a(++this.count) } }
await async_counter
// 1
await async_counter
// 2
await async_counter
// 3
await async_counter
// 4
await async_counter
// 5
async_counter.count
// 5

await のたびにカウントが増えています
通常の関数呼び出しとは違う構文で関数呼び出しを行えます

tag ``

みたいになにか色々と有効活用できそうな気はするのですがこれといって思いつきません

まあ テンプレートリテラルのタグは特殊な引数を使えたのに対して こっちは引数なしでメソッドを呼び出すだけです

await await await obj



fn()()()

と同じようなもので 引数を渡せないだけ不便になってます

() なしで関数呼び出せるあたり なんか面白い使いみちがありそうなんだけどな

async 関数と thenable object

async 関数と使う場合は thenable object を return したときに自動で then が呼び出されます

let n = 0
async function afn(){
return { then(r){ console.log("called"); r(n++) } }
}
afn()
console.log(n)
setTimeout(() => console.log(n), 100)
0
called
1

実行されるのは return 直後ではなく非同期ででした
knex のインスタンスみたいに then でなにかの実行するとき明示的に then を呼び出して引数をそのまま return しなくても関数を async 関数にするだけで済みます

function case1_callThen() {
return knex("table").then(rs => rs)
}

async function case2_useAwait() {
return await knex("table")
}

async function case3_asyncFunction() {
return knex("table")
}

case1 は自分で then を実行しています
ここで then を実行しなくても return したデータを使うために await や then を使うのでいらない気もします
返したところで使われなければ実行しない遅延評価になりますし
とは言っても取得しておいて使わないケースなんてまずないですし 関数内で責任を持って実行してもらいたいことがほとんどです(デバッグのしやすさ的にも
なので then を書いてますが そのまま返す then はなんか気持ち悪いです

case2 では await を入れました
これで then を自分で呼び出さなくても then が実行されます
これでもよかったのですが return がそこにあると await が無駄に見えるので外したいです

case3 では await を外しました
外すと return する値が thenable object だと実行されないんじゃ と思っていたのですが 実行されることがわかったのでこれで十分です
then メソッドで処理が実行されるタイプの結果を返すときは then が実行されることが保証されるasync 関数にしておいたほうが良さそうです