Successfully reported this slideshow.
Your SlideShare is downloading. ×

Async Enhancement

Ad

Async Enhancement
Grand-Frontend-Osaka 2015 Summer
2015.8.22

Ad

自己紹介
• かみやん (Twitter@kamiyam)

http://nantokaworks.com

• 主にJavaScriptでお仕事をしている人
• カメラ/自動車
Engineer

Ad

AGENDA
• JavaScriptと非同期処理
• 非同期の強みと弱み
• 非同期処理実行のエンドポイント
• ライブラリコールバック
• 非同期処理中のエラーハンドリング
• 複数非同期処理のコールバック

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Upcoming SlideShare
はじめてのVue.js
はじめてのVue.js
Loading in …3
×

Check these out next

1 of 71 Ad
1 of 71 Ad

More Related Content

Async Enhancement

  1. 1. Async Enhancement Grand-Frontend-Osaka 2015 Summer 2015.8.22
  2. 2. 自己紹介 • かみやん (Twitter@kamiyam)
 http://nantokaworks.com
 • 主にJavaScriptでお仕事をしている人 • カメラ/自動車 Engineer
  3. 3. AGENDA • JavaScriptと非同期処理 • 非同期の強みと弱み • 非同期処理実行のエンドポイント • ライブラリコールバック • 非同期処理中のエラーハンドリング • 複数非同期処理のコールバック
  4. 4. AGENDA • 非同期処理実行時のscopeのお話 • Promise • 革命的だった async モジュール • Promise準拠 • Q • まとめ
  5. 5. JavaScriptと非同期処理
  6. 6. 同期処理 2sec 5sec 1sec
  7. 7. 同期処理 2sec 5sec 1sec
  8. 8. 2sec 5sec 非同期処理 1sec
  9. 9. 2sec 5sec 非同期処理 1sec
  10. 10. 非同期の強みと弱み
  11. 11. // sorry node.js code var fs = require(“fs”); // Sync read directory var files = fs.readdirSync(“.”); console.log(files); console.log(“conmplate”); // Async read directory fs.readdir(“.", function(err, files){ if (err) throw err; console.log(files); }); console.log(“complate…?”);
  12. 12. プログラムのメインフローを邪魔せず 非同期で処理をnon blockingで実行 (する代わりに人が追いにくい流れに)
  13. 13. ドミノ倒しを想像するとわかりやすい
  14. 14. 非同期処理実行の エンドポイント
  15. 15. // document ready $(function(){ var $target = $(".initAnimetion”); $target.fadeIn( "slow", function() { setTimeout(function(){ $target.fadeOut( "slow", function() { console.log( "completed!!!" ); }) }), 2*1000 ); //2秒待つ }); });
  16. 16. 非同期の処理が終わった時に 実行されるコールバック関数が必要
  17. 17. ライブラリコールバック
  18. 18. 処理終了後の振る舞いは 利用者に委ねなければならない =コールバック関数が常に必要
  19. 19. // example (function($){ $.mySuperElegantLibrary = (function(){ var hoge = “”; var fuga = “”; return { miracleMethod: function(arg1,cb){ if(typeof(arg1) === 'function') cb = arg1; if((cb == null)) cb = $.noop; }, specialMethod: function(arg1,cb){ if(typeof(arg1) === 'function') cb = arg1; if((cb == null)) cb = $.noop; } } })(); })(jQuery);
  20. 20. 変数 cb は関数なのか文字列なのか undefinedなのかそうじゃないのか…
  21. 21. つきまとうコールバックとの闘い
  22. 22. 非同期処理中の エラーハンドリング
  23. 23. JavaScript にも try…catch あります
  24. 24. // example catching error (function(){ try{ throw new Error("エラーです"); }catch(e){ console.log(e); console.log("ここで正しい処理をします") } })();
  25. 25. // example catching error…??? // callback method inner is wonder land (function(){ try{ setTimeout(function(){ throw new Error("エラーです"); },1000); }catch(e){ console.log(e); console.log("ここでただしい処理をしますし(時間差)"); }})();
  26. 26. oh……
  27. 27. 複数非同期処理の コールバック
  28. 28. // async methods var A = function(cb){ setTimeout(function(){ cb("1秒掛かる処理を実行しました"); },1000); }; var B = function(cb){ setTimeout(function(){ cb("5秒掛かる処理を実行しました"); },5000); }; var C = function(cb){ setTimeout(function(){ cb("2秒掛かる処理を実行しました"); },2000); };
  29. 29. MISSION 処理A,B,C それぞれの結果を A,B,Cの順に配列に入れよ
  30. 30. //oh! very easy var result =[]; A(function(message1){ console.log(message1); result.push(message1); B(function(message2){ console.log(message2); result.push(message2); C(function(message3){ console.log(message3); result.push(message3); console.log("全ての処理がおわりました"); console.log(result); }); }); });
  31. 31. 同期処理 2sec 5sec 1sec
  32. 32. 同期処理 2sec 5sec 1sec
  33. 33. // parallels var allRequest = [A,B,C]; var result =[]; var counter = allRequest.length; allRequest.forEach(function(request,i){ console.log(i); // 0,1,2 request(function(message){ // Message出力(単体) console.log(message); result[i] = message; console.log(i); //0,2,1 <—-? if(--counter == 0){ // Message出力(全体) console.log("全ての処理がおわりました"); console.log(result); } }); });
  34. 34. 2sec 5sec 非同期処理 1sec
  35. 35. 2sec 5sec 非同期処理 1sec
  36. 36. 直列同期処理 処理内容 処理時間 処理① 処理② 処理③ 完了
  37. 37. 直列同期処理 処理内容 処理時間 処理① 処理② 処理③ ※ 前述サンプルのような処理の結果を以って
 次の処理を行う場合は別 同時に実行出来る処理は実行してしまいたい 完了
  38. 38. 並列同期処理 処理内容 処理時間 処理① 処理② 処理③ 完了
  39. 39. 並列同期処理 処理内容 処理時間 処理① 処理② 処理③ 完了 それぞれの処理を同時に実行し、一番遅い処理が
 完了するまで他は待機
  40. 40. ここで一旦話は変わり…
  41. 41. 非同期処理実行時の scopeのお話
  42. 42. JavaScript ループで回した時、 最後の方の要素しかなんか動かない問題
  43. 43. // no problem (function($){ $(function(){ // display none $("#content").children().hide(); //forEach $("#content").children().each(function(i,item){ // show $(item).fadeIn("slow"); }) }) })(jQuery)
  44. 44. // no problem (function($){ $(function(){ // display none $("#content").children().hide(); //forEach $("#content").children().each(function(i,item){ // show setTimeout(function(){ $(item).fadeIn("slow"); }, i * 1000); }) }) })(jQuery)
  45. 45. 大丈夫そう
  46. 46. // problems happen… // why!!! JavaScript looping!! (function($){ $(function(){ // display none $("#content").children().hide(); var children = $("#content").children(); for(var i=0; i < children.length; i++){ //for loop // show setTimeout(function(){ var item = children[i]; $(item).fadeIn("slow"); }, i * 1000); } }) })(jQuery)
  47. 47. // changing code… (function($){ $(function(){ // display none $(“#content”).children().hide(); var show = function(i){ // show setTimeout(function(){ var item = children[i]; $(item).fadeIn("slow"); }, i * 1000); } var children = $("#content").children(); for(var i=0; i < children.length; i++){ //for loop show(i) } }) })(jQuery)
  48. 48. // before parallels process var allRequest = [A,B,C]; var result =[]; var counter = allRequest.length; for(var i=0; i<allRequest.length; i++){ console.log(i); // 0,1,2 allRequest[i](function(message){ // Message出力(単体) console.log(message); result[i] = message; console.log(i); //3,3,3 <- !!! if(--counter == 0){ // Message出力(全体) console.log("全ての処理がおわりました"); console.log(result); } }); }
  49. 49. くろーじゃー…
  50. 50. Promise
  51. 51. 複数の非同期処理の最後 もうちょっとなんとかなりませんか?
  52. 52. 成功と失敗への遷移の確約
  53. 53. Promises/A+ https://promisesaplus.com/ https://developer.mozilla.org/ja/docs/Web/JavaScript/ Reference/Global_Objects/Promise MDN Promise http://caniuse.com/#feat=promises Can I Use
  54. 54. try~catchはエラーの確約だったはず…
  55. 55. // promise…then…catch var promise = new Promise(function(resolve,reject){ // example async progress doSomhing(function(error, data){ if(error) return reject(error); resolve(data); }) }); promise.then(function(data){ // with success }).catch(function(error){ // fail… })
  56. 56. // parallel…then…catch var promise1 = new Promise(function(resolve,reject){ // example async progress doSomhing(function(error, data1){ if(error) return reject(error); resolve(data1); }) }); var promise2 = new Promise(function(resolve,reject){ // 省略 resolve(data2) }); Promise.all([promise1,promise2]).then(function(result){ // with success console.log(result); // [data1,data2] }).catch(function(error){ // fail… })
  57. 57. resolve / reject に 結果の約束を結びつける
  58. 58. 革命的だった async モジュール (私の中では)
  59. 59. async.waterfall([function(next){ console.log(“1”); setTimeout(function(){ console.log(“1 complete”); next(null, 1); //next(error, result); },3000); },function(next){ console.log(“2”) setTimeout(function(){ console.log(“2 complete”); next(null, 2); //next(error, result); },3000); }], function(err, result1, result2 ){ console.log(err); // …null console.log(result1); //…1 console.log(result2); //…2 });
  60. 60. async. parallel([function(callback){ console.log(“1”); setTimeout(function(){ console.log(“1 complete”); callback(null, 1); //arg1…error,arg2….result },3000); },function(next){ console.log(“2”) setTimeout(function(){ console.log(“2 complete”); callback(null, 2); },1000); }], function(err, result){ console.log(err); // …null console.log(result); //…[“1”,”2”] });
  61. 61. Promise準拠
  62. 62. JavaScript Promises ※ 公開日 2013/12/16 http://www.html5rocks.com/ja/tutorials/es6/promises/ Conformant Implementations https://promisesaplus.com/implementations
  63. 63. Q
  64. 64. // promise…then…catch var promise = function(){ var deferred = q.deferred(); // example async progress doSomething(function(error, data){ if(error) return deferred.reject(error); deferred.resolve(data); }) return deferred.promise; }); promise.then(function(result){ // with success console.log(result); // data }).catch(function(error){ // fail… })
  65. 65. // parallel…then…catch var promise1 = function(){ var deferred = q.deferred(); // set deferred.reject(data1) & deferred.resolve(error) return deferred.promise; }); var promise2 = function(){ var deferred = q.deferred(); // set deferred.reject(data2) & deferred.resolve(error) return deferred.promise; }); q.all([promise1(), promise2()]).then(function(result){ // with success console.log(result); // [data1,data2] }).catch(function(error){ // fail… })
  66. 66. まとまらないまとめ
  67. 67. 非同期処理が複数実行される時、 その実行と完了を追うことが非常に重要
  68. 68. Promise準拠ライブラリをうまく使い分 けて半同期処理的なアプローチを
  69. 69. 他にGenerator /Yield もあるよ
  70. 70. 参考 • JavaScriptと非同期のエラー処理
 http://techblog.yahoo.co.jp/programming/javascript_error/ • あなたの知らない JavaScript Promise
 https://gist.github.com/kuu/e182d361520e70a158c9 • Effective ES6
 http://www.slideshare.net/teppeis/effective-es6
  71. 71. ご清聴ありがとうございました

×