とりあげる課題とその問題点
今回取り上げるものは以下のようなコード
実例はkuromoji.js
(A: T, B: VoidFunction) => void
kuromoji/example/load-node.js
"use strict";
var kuromoji = require("../src/kuromoji");
var DIC_DIR = "dict/";
// Load dictionaries from file, and prepare tokenizer
kuromoji.builder({ dicPath: DIC_DIR }).build(function (error, tokenizer) { // ここが問題のコールバック
var path = tokenizer.tokenize("すもももももももものうち");
console.log(path);
module.exports = tokenizer;
});
// ここでtokenizerは使えない
このtokenizerはこのままではコールバック関数外では利用できない。
これはスコープの関係上当たり前だが、少々使いづらい。
しかもコールバック地獄の原因なので使いたくない
というわけでこれを
test
const kuromoji = await tokenizer();
const res = kuromoji
.tokenize('すもももももももものうち')
.map(t => t.surface_form);
expect(res).toEqual(['すもも', 'も', 'もも', 'も', 'もも', 'の', 'うち']);
このようにfunctionalに書きたい。
解決策
new promiseする
typescript
import kuromoji, { Tokenizer, IpadicFeatures, TokenizerBuilder } from 'kuromoji';
const builder: TokenizerBuilder<IpadicFeatures> = kuromoji.builder({
dicPath: 'node_modules/kuromoji/dict',
});
export const tokenizer = () => new Promise<Tokenizer<IpadicFeatures>>(done => {
builder.build((_err, tokenizer) => {
done(tokenizer);
});
});
こうすると
test
const kuromoji = await tokenizer();
const res = kuromoji
.tokenize('すもももももももものうち')
.map(t => t.surface_form);
expect(res).toEqual(['すもも', 'も', 'もも', 'も', 'もも', 'の', 'うち']);
まとめ
取り上げたコードの名称を「継続」っていうらしいです。
async/await世代なので少し詰まった。
参考文献
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function