Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

Promise 対応していないコールバック形式のライブラリーを Promise にしたい

$
0
0

Node.js v8.1 で util.promisifyっていう関数が追加されてたんですね。 古き良き伝統にしたがったコールバック形式の関数を Promise を返す形にしてくれる。つまり await 出来るようになる!

nodejs.org

ということで、今時コールバック形式のライブラリなんて…と思ってたら azure-storageがそれでした。 ということで使ってみよう。

使い方は簡単。

const f = util.promisify(hogehoge);

のようにコールバック形式の関数を渡してやると Promise を返す関数になるので…

await f();

とすれば OK。

じゃぁこんな感じに使えるかな。

import express from'express';import util from'util';import azure from'azure-storage';interface EntityType {
    PartitionKey: azure.TableService.EntityProperty<string>;
    RowKey: azure.TableService.EntityProperty<string>;
    Value: azure.TableService.EntityProperty<string>;}// Azure ストレージエミュレーターにつなぐconst client = azure.createTableService('AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;');asyncfunction getAll(){await util.promisify(client.createTableIfNotExists).bind(client)('test');const query =new azure.TableQuery().where('PartitionKey eq ?','a').select('Value');// 本当は util.promisify(client.queryEntities<EntityType>) みたいにしたかった。この場合どうするのが正解なんだろうreturnawait util.promisify(client.queryEntities).bind(client)('test', query,nullasany)as 
        azure.TableService.QueryEntitiesResult<EntityType>;}const app = express();
app.get('/',async(req, res)=>{const result =await getAll();
    res.json(result.entries.map(x => x.Value._));});

app.listen(3000);

注意点は、関数内部の this をちゃんと bind で指定してあげることくらいかな?

適当にデータつっこんだテーブルを用意して実行して localhost:3000 にアクセスすると…

f:id:okazuki:20190911202826p:plain

返ってきた!!

実際使うとしたら都度都度 util.promisify するのではなく、都合のいい感じのラッパークラスを用意する感じかなぁ?

import express from'express';import util from'util';import azure from'azure-storage';interface EntityType {
    PartitionKey: azure.TableService.EntityProperty<string>;
    RowKey: azure.TableService.EntityProperty<string>;
    Value: azure.TableService.EntityProperty<string>;}// こういうラッパークラスにめんどくさい処理は押し込んでおいて…class TableService {constructor(private tableService: azure.TableService){}public createTableService = util.promisify(this.tableService.createTableIfNotExists).bind(this.tableService);private _queryEntities = util.promisify(this.tableService.queryEntities).bind(this);publicasync queryEntities<T>(tableName: string, query: azure.TableQuery, token: azure.TableService.TableContinuationToken){returnawaitthis._queryEntities(tableName, query, token)as
            azure.TableService.QueryEntitiesResult<T>;}}const innerClient = azure.createTableService('AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;');const client =new TableService(innerClient);asyncfunction getAll(){// 使う側は意識しなくてよくするawait client.createTableService('test');const query =new azure.TableQuery().where('PartitionKey eq ?','a').select('Value');returnawait client.queryEntities<EntityType>('text', query,nullasany);}const app = express();
app.get('/',async(req, res)=>{const result =await getAll();
    res.json(result.entries.map(x => x.Value._));});

app.listen(3000);

まとめ

ライブラリー側で await 出来るように Promise 返してくれるようにしてほしさある。


Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>