Save 37% off PRO during our Black Friday Sale! »

AsyncStorageをNodeのREPLから操作するためにTop-levelでawaitしたい人生だった

B72422afc5f3ffc844f672b59122e16d?s=47 joe_re
July 14, 2017

 AsyncStorageをNodeのREPLから操作するためにTop-levelでawaitしたい人生だった

五反田.js #8 LT資料

B72422afc5f3ffc844f672b59122e16d?s=128

joe_re

July 14, 2017
Tweet

Transcript

  1. AsyncStorage をNode の REPL から操作するために Top­level でawait したい 人生だった @joe_re

  2. Who am I? twitter: @joe_re github: @joe­re working in freee.K.K

  3. What is AsyncStorage? ReactNative の標準で搭載されたkey­value ストレージ 気軽にReactNative に永続化したいデータを持つときに便利 ReactNative で使えるLocalStorage

    みたいなもの
  4. Example Persisting date: try { await AsyncStorage.setItem('@MySuperStore:key', 'I like to

    save it.'); } catch (error) { // Error saving data } Fetching date: try { const value = await AsyncStorage.getItem('@MySuperStore:key'); if (value !== null){ // We have data!! console.log(value); } } catch (error) { // Error retrieving data }
  5. AsyncStorage をNode のREPL から操作したいという欲望 AsyncStorage には外部から叩けるAPI は用意されていない 開発中にデータ構造が変わったときにアプリケーションに データを修正するためのコードを書くのは面倒 ちゃんとデータが保存されたかどうか確かめるのも面倒

    REPL からAsyncStorage のAPI を叩きたい (rails console みたいなイメージ)
  6. 作った https://github.com/joe­re/async­storage­repl

  7. DEMO

  8. 仕組み Node とReactNative との通信はWebsocket で行う REPL 起動時に子プロセスとしてReactNative アプリケーションと通信するWSS を立ち上げる REPL

    とWSS はプロセス間通信を行う
  9. イメージ図

  10. ん?

  11. どうしてこうなった

  12. Node.js ではTop Level で非同期処理の 結果を扱えない 人類はES2017 よりasync/await を獲得したが、 await はasync

    function の中でしか使えない // ng function request { const response = await fetch( '/data.json' ); const json = await response.json(); const result = await hydrateSomehow(json); return result; } // ok function async request { const response = await fetch( '/data.json' ); const json = await response.json(); const result = await hydrateSomehow(json); return result; }
  13. REPL で Promise オブジェクトを 扱おうとすると.. > let out = null;

    > promiseObj.then((res) => { out = res }); > out // finally available here
  14. だるすぎワロた

  15. Top­level await is a footgun https://gist.github.com/Rich­ Harris/0b6f317657f5167663b493c722647221 Top­level のawait を許すと1

    つの依存を解決するだけでも、 その先の関係のない処理まで止めざるを得ない await は直列を強要するので、ネットワークを介した処理の 並列化ができない
  16. Example(borrow from Harris) // main.js import './foo.js'; import './bar.js'; //

    foo.js await delay( Math.random() * 1000 ); console.log( 'foo happened' ); // bar.js await delay( Math.random() * 1000 ); console.log( 'bar happened' );
  17. 将来的にはTop­level await が できるかも? https://github.com/tc39/ecmascript­asyncawait/issues/9

  18. それはそれとしてNode のREPL に 例外的に入る可能性も https://github.com/nodejs/node/issues/13209

  19. 今回はこのような実装に _resolveMessageFromRN(fileName) { let json = {}; let received =

    false; for (let i = 0; i < this.timeout; i++) { sleep.msleep(100); const fileContent = fs.readFileSync(fileName, 'utf8'); if (fileContent) { json = JSON.parse(fileContent); delete this.que[Number(json.queId)]; received = true; break; } sleep.msleep(900); } fs.unlinkSync(fileName); if (!received) { throw new Error("can't receive response from ReactNative Application"); } if (json.error === 1) { throw new Error(json.message); } return json.result; }
  20. そうは言っても結構便利です。 ReactNative のお供にぜひ!

  21. ありがとうございました