potjs
Pot.js Blog
17 posts
Don't wanna be here? Send us removal request.
potjs · 12 years ago
Text
Pot.js 1.21 and PotLite.js 1.38 released.
Pot.js 1.21 と PotLite.js 1.38 リリースしました。 Pot.js は非同期処理を中心とした JavaScript ライブラリです。 概要などの詳しい詳細は以下のリファレンスを参照ください。
Pot.js + PotLite.js - Document and Reference
Download
Pot.js+PotLite.js-zip
Changelog
ja:
Pot.Deferred コールバック内で FileReader を返したときの不具合を修正
JSDoc コメントが変だったのを修正
Blob コンストラクタと BlobBuilder ���実装の違いを吸収する Pot.createBlob() 関��を実装
Pot.equals() に長さの違うオブジェクトを渡した時に不正な結果になる不具合を修正
jQuery.ajax を Pot.Deferred 化する Pot.deferrizejQueryAjax() をスクリプトの読み込み順序に関係なく実行できるよう調整
Pot.serializeToQueryString() で Boolean をそのまま文字列化するよう変更
要素のリサイズ値を取得できる Pot.getResizeSize() を実装
DOM 要素が画面上に見えてるか判別する Pot.isElementInView() 関数を実装
オブジェクトを文字列でダンプした結果を返す Pot.dump() 関数を実装
既存コンストラクタのプロパティに不具合があったのを修正
prototype と共にコンストラクタを生成できる Pot.createConstructor() を実装
Pot.debug() のエラー版となる Pot.error() を追加
Image インスタンスかどうか判別する Pot.isImage() を実装
Pot.maybeDeferred() に jQuery.Deferred や JSDeferred など他の Deferred インスタンスを渡すと Pot.Deferred インスタンス化するよう改訂
Pot.Deferred コールバック内で Image インスタンスを返すと then() で onload、rescue() で onerror が拾えるよう改訂
en:
Fixed Deferred when returned FileReader with event callback.
Fixed JSDoc comment and return value.
Added Pot.createBlob() function for browser compatibility with BlobBuilder and Blob constructor.
Fixed bug: Pot.equals() will return true for objects that have different lengths.
Improved Pot.deferrizejQueryAjax() for jQuery plugin.
Changed Pot.serializeToQueryString() to handle as it is Boolean (true and false).
Added Pot.getResizeSize() function.
Added Pot.isElementInView() function.
Added Pot.dump() function.
Fixed the constructor property initialization.
Added Pot.createConstructor() function.
Added Pot.error() function.
Added Pot.isImage() function.
Improved Pot.maybeDeferred() to convert to an instance of Pot.Deferred from jQuery.Deferred and JSDeferred.
Improved Pot.Deferred callback to ensure an instance of Image loading.
Pot.createBlob() は、ブラウザ環境に Blob が実装されていたら Blob を、BlobBuilder が実装されていたら BlobBuilder を使って Blob を生成します。
Pot.begin(function() { var blob = Pot.createBlob('hoge', 'text/plain'); // 第2引数は任意 var reader = new FileReader(); reader.readAsText(blob); return reader; }).then(function(res) { Pot.debug(res); // 'hoge' });
Pot.serializeToQueryString() は、以前は true や false を空文字 '' と扱っていたのを、'true', 'false' として扱うようになりました。 これは、Pot.request() でのパラメータの指定でも同じです。 Pot.dump() は、オブジェクトなど任意の値をダンプした文字列を返します。 参照は #1 などの表現になります。
var reg = /^[a-z]+$/g; var err = new Error('error!'); var str = new String('hello'); var arr = [1, 2, 3, {a: 4, b: 5, c: true}, false, null, void 0]; var obj = { key1 : 'val1', key2 : 'val2', arr : arr, arr2 : arr, strs : [str, str], err : err, err2 : err, reg1 : reg, reg2 : reg, reg3 : reg }; obj.obj = obj; Pot.debug( Pot.dump(obj) ); // #0 { // key1: "val1", // key2: "val2", // arr: #3 [ // 1, // 2, // 3, // { // a: 4, // b: 5, // c: true // }, // false, // null, // undefined // ], // arr2: #3, // strs: [ // #5 (new String("hello")), // #5 // ], // err: #6 (new Error("error!")), // err2: #6, // reg1: #8 (new RegExp(/^[a-z]+$/g)), // reg2: #8, // reg3: #8, // obj: #0 // }
Pot.createConstructor() は、prototype と共にコンストラクタを生成して返します。 {Function} Pot.createConstructor([name ,] proto [, init]); name が指定されると、toString に使われます。 init は初期化する関数名または関数を任意で指定します。 引数 init が省略されて、proto 内に 'init' というメソッドがあると、それを初期化する関数と扱います。
// proto 内に init で初期化メソッドを指定 var Hoge = Pot.createConstructor('Hoge', { init : function(a, b, c) { this.value = a + b + c; }, getHoge : function() { return 'hogehoge'; } }); Pot.debug(new Hoge(1, 2, 3).value); // 6 Pot.debug(new Hoge().getHoge()); // 'hogehoge'
// 初期化関数を関数で指定 var Fuga = Pot.createConstructor({ value : 1, addValue : function(v) { this.value += v; return this; }, getValue : function() { return this.value; } }, function(a, b, c) { this.value += a + b + c; }); Pot.debug(new Fuga(1, 2, 3).value); // 7 Pot.debug(new Fuga(1, 2, 3).addValue(10).getValue()); // 17
// initialize という名前で初期化関数を指定 var Piyo = Pot.createConstructor('Piyo', { initialize : function(a, b, c) { this.value = a + b + c; }, getValue : function() { return this.value; } }, 'initialize'); Pot.debug(new Piyo(10, 20, 30).getValue()); // 60
Pot.maybeDeferred() は、jQuery.Deferred や JSDeferred など、他のライブラリの Deferred インスタンスを Pot.Deferred インスタンス化できるようになりました。
// jQuery.Deferred を Pot.Deferred 化 var d = $.Deferred(); d.done(function() { Pot.debug(1); }).done(function() { Pot.debug(2); }); // Pot.Deferred インスタンス化 Pot.maybeDeferred(d).then(function() { Pot.debug(3); }).ensure(function() { Pot.debug(4); }); d.resolve(); // output: // 1 // 2 // 3 // 4
JSDeferred と値の受け渡し
// JSDeferred インスタンス var d = new Deferred().next(function(res) { Pot.debug(res); // 1 return res + 1; }); // Pot.Deferred インスタンス化 Pot.maybeDeferred(d).then(function(res) { Pot.debug(res); // 2 return res + 1; }).ensure(function(res) { Pot.debug(res); // 3 }); d.call(1);
FileReader と同じく Pot.Deferred コールバック内で Image インスタンスを返すと then() で onload、rescue() で onerror が拾えるようになりました。
Pot.begin(function() { var img = new Image(); img.src = 'http://api.polygonpla.net/img/logo/pot.js.mini.png'; return img; }).then(function(img) { // ロード完了時 (onload) Pot.debug(img.width); // 300 }).rescue(function(err) { Pot.debug(err); // エラー時 (onerror) });
詳しい詳細は以下のリファレンスを参照ください。
Reference
Pot.js + PotLite.js - Document and Reference
Repository
polygonplanet/Pot.js - GitHub
3 notes · View notes
potjs · 12 years ago
Text
Pot.js 1.20 and PotLite.js 1.37 released.
Pot.js 1.20 と PotLite.js 1.37 リリースしました。
Download
Pot.js+PotLite.js-zip
Changelog
ja:
内部変数 StopIteration を除去
Pot.Struct.pairs で未知の変数を修正
Pot.Struct.equals() で再帰的に比較するよう改訂
Pot.Deferred.parallel に Deferred を含む関数を渡すと想定外の動作になるのを修正 (Thanks coffeegyunyu)
Pot.sprintf() に数値を 3桁区切りする型指定子 'n' を追加
en:
Fixed internal StopIteration.
Fixed bug: undefined function 'pairs' in Pot.pairs (Pot.Struct.pairs).
Fixed Pot.equals() recursive compares (Pot.Struct.equals).
Fixed Pot.Deferred.parallel.
Added Pot.sprintf format 'n' (Pot.Format.sprintf).
Reference
Pot.js + PotLite.js - Document and Reference
Repository
polygonplanet/Pot.js - GitHub
2 notes · View notes
potjs · 12 years ago
Text
Pot.js非同期イテレータだけの軽量版を作ってみました
Pot.js の実装のうち Pot.Deferred.forEach などの 非同期/同期イテレータだけにした軽量タイプを PotPico.js として作ってみました。 サイズは約 50KB で、PotLite.js より軽くなりました。 単に CPU 負荷を抑えて JavaScript を実行したい時とか、 Pot.Deferred や Pot.js のイテレータがどんなものか触ってみるきっかけになれたらと思ってます。 サイズと実装は、
Pot.js >>>>>> PotLite.js >>> PotPico.js (full) (非同期処理のみ) (イテレータとDeferredのみ)
こんな感じです。 PotPico.js はイテレータに必要なものだけにして、 Minify 用に少し最適化した感じです。 なので Pot.js / PotLite.js とまったく同じに使えて、リファレンス も同じく参照できます。
Download
zip package
Download zip
PotPico.js
potpico.min.js - Production (Minified)
Document and Reference
Pot.js - Document and Reference
PotPico.js で利用できる関数/オブジェクトのリファレンス:
Core の一部
Pot.Deferred
Pot.Iter (イテレータ)
JSDoc
Closure Compiler でソースコードから自動生成したドキュメント。
PotPico.js JSDoc
Compatibility
PotPico.js は Pot.js と同じく以下の環境で動きます。
Mozilla Firefox *
Internet Explorer 6+
Safari *
Opera *
Google Chrome *
以下の環境でも利用可能です。
Greasemonkey (userscript)
Mozilla Firefox Add-On (on XUL)
Node.js
Other non-browser environment
TestRun
以下のページで動作テストして確認できます。
PotPico.js TestRun
License
Dual licensed under the MIT and GPL v2 licenses.
PotPico.js のページ
PotPico.js - JavaScript Async Library
PotPico.js は今のところレポジトリ (GitHub /master) に含まれてません。 PotLite.js もあるのに、これ以上そういうの増やすのもどうかと思って API サーバのほうに置いてます。 Pot.js より手軽でイイ! ていうことになったら master に含めようと思ってます (もし使ってくれる方がいたら…)。 もしくは、PotLite.js を PotPico.js として置き換えてもいいかも (WebWorker とかたぶん使われてない)。 Pot.js のほうの情報についてはリファレンス等から参照ください。
レポジトリ
polygonplanet/Pot.js - GitHub
その他、なにか問題・バグ・感想・指摘などあれば、 コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。
19 notes · View notes
potjs · 13 years ago
Text
Pot.js 1.19 and PotLite.js 1.36 released.
Pot.js 1.19 と PotLite.js 1.36 リリースしました。
Download
Pot.js+PotLite.js-zip
Changelog
ja:
Pot.MimeType に ogg 追加
Pot.base64Decode() で Pot.base64URLEncode() したのもデコード可能に
Pot.alphanumSort() に添字の指定可能なコールバック関数を引数に指定できるよう追加
Pot.isTypedArray() と Pot.isArrayBufferoid() を実装
ArrayBuffer と DataView をクロスブラウザにミックスしたような Pot.ArrayBufferoid の実装
文字コード変換関数 Pot.convertEncodingToUnicode() の実装 (Thanks haxe)
WebKitBlobBuilder が自動文字コード判別できないのを Fix
Pot.Base64 で Typed Array ��扱えるよう改訂
Pot.Crypt で Typed Array も扱えるよう改訂
Pot.isArrayBuffer() の実装
Pot.Signal で FileReader によるエラーが発生するのを修正
Pot.ArrayBufferoid から Array, String, Blob に変換するのを最適化
Pot.UTF8 と Pot.ArrayBufferoid でサロゲートペアの問題を修正 (Thanks kefir_)
Pot.DropFile に 'readAs', 'onProgress', 'onProgressFile' オプション/イベントを追加
Pot.DropFile のオプションのイベントコールバック関数に渡る引数を変更
Pot.DropFile でテキストかどうか判別するのを改善
Pot.toCharCode() を実装 (Pot.Text)
Pot.isBlob() と Pot.isFileReader() を実装
Pot.Deferred コールバック内で FileReader を返すと結果ファイルが次のチェインに渡るよう改訂
en:
Added ogg in Pot.MimeType.
Improved compatibility with Pot.base64Decode() and Pot.base64URLEncode().
Added Pot.alphanumSort() callback argument to specify object property.
Added Pot.isTypedArray() and Pot.isArrayBufferoid() in Core.
Implemented Pot.ArrayBufferoid.
Added Pot.convertEncodingToUnicode().
Fixed: WebKitBlobBuilder cannot detect encoding automatically.
Improved Pot.Base64 to treat Typed Array.
Added support for specify Array (Typed Array) argument with Crypt functions.
Added Pot.isArrayBuffer() function in Core.
Fixed exception by FileReader in Pot.Signal.
Optimized Pot.ArrayBufferoid conversion functions.
Fixes the surrogate pair range bug in Pot.UTF8 and Pot.ArrayBufferoid reported by kefir_.
Added "readAs", "onProgress" and "onProgressFile" event options in Pot.DropFile.
Changed DropFile.prototype.on* event callback arguments in Pot.DropFile.
Fixed the text mode detection in Pot.DropFile.
Added Pot.toCharCode() function in Pot.Text.
Added Pot.isBlob() and Pot.isFileReader() function in Core.
Improved Pot.Deferred can replies if an instance of FileReader returned in callback.
大きな(?)変更点は Pot.DropFile のイベント関数の引数が変わったことです。
var dropFile = new Pot.DropFile(elem, { onLoadImage : function(data, name, size, type) {}, onLoadText : function(data, name, size, type) {}, onLoadUnknown : function(data, name, size, type) {}, // こうだったのが↓の引数になりました onLoadImage : function(data, fileinfo) { var name = fileinfo.name; var size = fileinfo.size; var type = fileinfo.type; }, onLoadText : function(data, fileinfo) { // 上と同じ }, onLoadUnknown : function(data, fileinfo) { // 上と同じ }, // そして実装された進歩時のイベント onProgress : function(percent) { // 複数ファイルがドロップされた時も含めて // ファイル全部に対する読み込み状況のパーセンテージ console.log(percent + '%'); }, onProgressFile : function(percent, fileinfo) { // ファイル 1つに対する読み込み状況のパーセンテージ console.log(fileinfo.name + ': ' + percent + '%'); }, // ドロップされたファイルの読み込む形式が指定できるようになりました readAs : 'arraybuffer' // - readAs : // - 'text' : テキストとして読み込みます (readAsText) // - 'binary' : バイナリとして読み込みます (readAsBinaryString) // - 'arraybuffer' : ArrayBufferとして読み込みます (readAsArrayBuffer) // - 'datauri' : DataURIとして読み込みます (readAsDataURL) // - null : テキストファイルは 'text'、それ以外は 'datauri' で読み込みます (デフォルト) });
この変更は リファレンス も更新してあります。 Pot.DropFile の 動作サンプル そして、主な実装は Pot.ArrayBufferoid です。 ArrayBufferoid は、ArrayBuffer (Typed Array) の変換器を中心として DataView の機能も兼ねたストリームに適したオブジェクト/コンストラクタです。 Array.prototype も持っててちょっとカ���スに混ぜてますが、 ��ロスブラウザに使えるようにしたのが目的です。 まだリファレンスが作れてない (2012-05-13 現在) ので、ソースコードまたは JSDoc を参照ください。
var buffer = new Pot.ArrayBufferoid(); var i = 0; // 配列のように値を埋めたり buffer[i++] = 255; buffer[i++] = 254; // Array.prototype.push を使ってみたり buffer.push(253); buffer.push(252); // DataView がない環境でも使えるように Pot.debug(buffer.getUint16(0, true)); // 65279 // length は size() を使います Pot.debug('buffer.length = ' + buffer.size()); // 4 // Typed Array に変換 (ない環境は Array になる) var arrayBuffer = buffer.toArrayBuffer(); var uint8Array = buffer.toUint8Array(); // ストリームな使い方 buffer.seek(0); var data1 = buffer.read(1); Pot.debug(data1[0]); // 255 Pot.debug(buffer.tell()); // 1 var data2 = buffer.read(2); Pot.debug(data2); // [254, 253] buffer.seek(0); buffer.write([100, 101]); Pot.debug(buffer); // [100, 101, 253, 252]
でもやっぱり Typed Array を使うような場合は速度を重視すると思います。 その場合、直接 Uint8Array などを扱ったほうが速いです。 ArrayBufferoid はクロスブラウザなバッファとして扱うと楽になってます。
// 変換用に利用したり var uint8array = Pot.ArrayBufferoid.toUint8Array([0x61, 0x62, 0x63]); // コピー時に利用したり var copy = Pot.ArrayBufferoid.copyBuffer(uint8array); // 文字列に変換したり var binary = Pot.ArrayBufferoid.bufferToBinary(copy); Pot.debug(binary); // 'abc' // 巨大な配列を var view = new Pot.ArrrayBufferoid(1000000).toUint8Array(); for (var i = 0; i < 1000000; i++) { view[i] = 0x61; } // 非同期で負荷をかけずに変換したり Pot.ArrayBufferoid.bufferToBinary.deferred(view).then(function(res) { Pot.debug(res); // 'aaaaaaaaaaa...' }); // UTF-16 文字列から UTF-8 Buffer に変換したり戻したり var s = 'hogeほげ'; var buffer = Pot.ArrayBufferoid.stringToBuffer(s); var string = Pot.ArrayBufferoid.bufferToString(buffer); Pot.debug(buffer); // buffer: // [104, 111, 103, 101, 227, 129, 187, 227, 129, 146] Pot.debug(s === string); // true
といった時に役立てると思います。 そして、個人的に楽になった改善点は Pot.Deferred のコールバック関数内で FileReader インスタンスを返すと ファイル読み込みが完了してから次のチェインが実行され、 結果に読み込んだファイルが渡るようになりました。
Pot.Deferred.begin(function() { // readAsTextの例 var reader = new FileReader(); var bb = new Pot.System.BlobBuilder(); bb.append('hoge'); reader.readAsText(bb.getBlob()); // readerを返すと結果が次のチェインで取得できる return reader; }).then(function(res) { // 結果は FileReader の onload の event.target.result Pot.debug(res); // 'hoge' }).rescue(function(err) { // エラー時 (FileReader の onerror) alert(err); });
onload, onloadend 等を設定していても同じに動作します。 Deferred と相性いいイベントの関係だと楽でいいですね!
2 notes · View notes
potjs · 13 years ago
Text
Pot.js Blog移動(作成)しました
Pot.js 関連の情報を分けました。 今までは 圧縮電子どうのこうの のほうになんでも書いちゃってたのですが これからはリリースノートなどの Pot.js / PotLite.js に関する情報はこのブログに書いていきます。 Tumblr でブログとして思ったように作れるか、ちょっと心配でしたがなんとかなりました。 このブログではテキストのみポストでいくと思います (テキスト以外テンプレート書いてない)。 Tumblr のブログとしての機能的なことは Tumblrをブログとして利用する-実践編- | JSer.info がとても参考になりました。 まだテンプレート作ったばっかしなのでバグとかリンク変だよとかありましたら polygon_planet まで伝えてくれるとうれしいです。
26 notes · View notes
potjs · 13 years ago
Text
JavaScriptライブラリ Pot.js 関連リンクまとめ
Pot.js 関連のリンクまとめ
JavaScript ライブラリ Pot.js に関する記事やサンプルの紹介です。 Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。 MOONGIFT さんの記事 で紹介されたのもあって、せっかくなのでまとめてみました。
jQueryとも組み合わせて使える汎用的ユーティリティライブラリ「Pot.js」 - MOONGIFT
MOONGIFT さんの記事
Pot.js 公式 リファレンス
リファレンスとドキュメントです。このリファレンス自体が Pot.js で作られています。 ほぼすべての情報はここに集約されています。
jQuery.each と Pot.js イテレータで CPU 使用率比較グラフ
jQuery.each と Pot.js イテレータで CPU 使用率を比較したグラフと、別の視点から高速化に繋げる方法。
JavaScript whileループとPot.Deferred.forEverイテレータでCPU使用率を比較-Pot.js+PotLite.jsリリースノート
ループ処理を jsFiddle で実際に実行できる CPU 使用率比較のサンプル。
Pot.js CPU benchmark/Compare TEST - jsFiddle
JavaScript 「while文」と「Pot.js非同期イテレータ」のCPU負荷を比較。 CPU 使用率がわかるアプリ (タスクマネージャ) などを起動して比較してみてください。 「応答のないスクリプト」警告を有効にしておくとわかりやすいです。
並列処理のWorkerぽいWorkeroid実装。JavaScriptライブラリPot.js 1.17 リリース
並列処理の HTML5 Web Workers をクロスブラウザで動かせる Pot.Workeroid の紹介とリリースノート。
Pot.js Workeroid.terminate() Test (Native Web Workers + Emulator) - jsFiddle
HTML5 Web Workers を使いやすくした Pot.Workeroid を使った並列処理の動作サンプル (子スレッドからひたすら素数を返す)。
HTML5 File APIでドラッグ&ドロップのサンプル-Pot.js+PotLite.jsリリースノート
HTML5 File API とドロップイベントを楽に書ける Pot.DropFile の紹介と動作サンプル。
同期処理を非同期に変換-JavaScriptライブラリPot.js+PotLite.jsリリースノート
for, for-in, do, while などの同期ループを非同期に変換して負荷分散する関数の実装と紹介。
アスペクト指向っぽく書ける Signal実装
イベントに Before, After を組み合わせてアスペクト指向 (AOP) っぽいプログラミングが可能な Pot.Signal の紹介。
jsFiddle サンプル集 - JavaScriptライブラリ Pot.js + PotLite.js リリースノート
非同期で処理する md5 や圧縮解凍の jsFiddle 動作サンプル。
Pot.js Pot.br() function Test - jsFiddle
HTML の適した場所に br タグを挿入する関数の動作サンプル。
Pot.js - Pot.md5 Async Test - jsFiddle
md5 を非同期で実行する動作サンプル。
Pot.js Pot.Archive.AlphamericString Test - jsFiddle
非同期で文字列の圧縮解凍するサンプル。
Pot.js - Pot.ReplaceSaver Sample - jsFiddle
文字列の置換代行の動作サンプル
JavaScriptライブラリ Pot.js のチートシートと壁紙用ジェネレータ作りました
Pot.js (PotLite.js) のチートシートとジェネレータ。
JavaScriptライブラリ Pot.js 1.18 リリース。strict modeになりました
'use strict' でライブラリ全体が strict mode になりました。
2012-02-27のJS: Pot.jsリファレンス、WebStorm紹介、grunt | JSer.info
JSer.info さんで Pot.js リファレンス完成記念と概要が掲載されています。
2012-04-15のJS: jQuery Mobile 1.1.0、CoffeeScript 1.3.1、YUI 3.5.0 リリース | JSer.info
strict mode になった Pot.js が紹介されています。
Pot.js is a utility library that can execute JavaScript without burdening CPU. | Hacker News
Hacker News。
Pot.js + PotLite.js - JavaScript Async + String Utility Library - Echo JS
Echo JS。
Pot.js / PotLite.js
Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。 PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。
ダウンロード
Pot.js / PotLite.js 最新
マニュアル
Pot.js + PotLite.js - Document and Reference - JavaScript Async Utility Library
その他の情報についてはマニュアル/マニュアルからのリンク から参照ください。
レポジトリ
polygonplanet/Pot.js - GitHub
その他、なにか問題・バグ・感想・指摘などあれば、 コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。
body div.pot-overlay-content { line-height: 1.4; } .pot-overlay-content h2 { font-size: 150%; margin-top: 38px; margin-bottom: 30px; } dl dt { font-style: normal; font-weight: bold; } body div.pot-separator-image, body div.pot-separator-image-full { display: block; margin: 10px; padding: 0; text-align: left; } body div.pot-separator-image a, body div.pot-separator-image-full a { margin-left: 1em; margin-right: 1em; } body div.pot-separator-image a img, body div.pot-separator-image-full a img { border: 2px solid #999; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } body div.pot-separator-image a img.notify, body div.pot-separator-image-full a img.notify { border: 0 none; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; } body div.pot-separator-image a img.portrait, body div.pot-separator-image-full a img.portrait { border: 1px solid #666; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; } body div.pot-overlay-content div.pot-separator-image-full { padding-left: 0 !important; padding-right: 0; margin-left: 0 !important; margin-right: 0; } body div.pot-overlay-content div.pot-separator-image-full a { margin-left: 0; margin-right: 0; } body .potjs-matome-item { margin: 1em; margin-left: 0; font-weight: bold; font-size: 120%; } body .potjs-matome-item-sub { margin: 0 1em 3em 0; }
2 notes · View notes
potjs · 13 years ago
Text
JavaScriptライブラリPot.js 1.18 リリース。strict modeになりました
Pot.js 1.18 と PotLite.js 1.35 リリースしました。
変更点など
'use strict'つけてライブラリ全体が strict mode になりました
DropFile が Firefox で不具合出てたので修正
minify したときの最適化
などで、とくに機能の変更はありません。 ねんがんの strict mode にできたので、'use strict' 内で取り込まれても問題なく動きます。 全体を strict mode にするためにソースコードの表現はけっこう変わってますが 動作はむしろ速くなって、サイズがちょっとだけ減りました。 リファレンスのほうは、定義してある関数をとりあえず全部メニューに載せるようにしました。 でもメニューだけで中身の html が無いので、はやいとこ作りたいなと思ってます。
Pot.js / PotLite.js
Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。 PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。 ダウンロード
Pot.js / PotLite.js 最新
マニュアル
Pot.js + PotLite.js - Document and Reference - JavaScript Async Utility Library
その他の情報についてはマニュアル/マニュアルからのリンク から参照ください。
レポジトリ
polygonplanet/Pot.js - GitHub
その他、なにか問題・バグ・感想・指摘などあれば、 コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。
body div.pot-overlay-content { line-height: 1.4; } .pot-overlay-content h2 { font-size: 150%; margin-top: 38px; margin-bottom: 30px; } dl dt { font-style: normal; font-weight: bold; } body div.pot-separator-image, body div.pot-separator-image-full { display: block; margin: 10px; padding: 0; text-align: left; } body div.pot-separator-image a, body div.pot-separator-image-full a { margin-left: 1em; margin-right: 1em; } body div.pot-separator-image a img, body div.pot-separator-image-full a img { border: 2px solid #999; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } body div.pot-separator-image a img.notify, body div.pot-separator-image-full a img.notify { border: 0 none; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; } body div.pot-separator-image a img.portrait, body div.pot-separator-image-full a img.portrait { border: 1px solid #666; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; } body div.pot-overlay-content div.pot-separator-image-full { padding-left: 0 !important; padding-right: 0; margin-left: 0 !important; margin-right: 0; } body div.pot-overlay-content div.pot-separator-image-full a { margin-left: 0; margin-right: 0; }
1 note · View note
potjs · 13 years ago
Text
JavaScriptライブラリ Pot.js のチートシートと壁紙用ジェネレータ作りました
Pot.js チートシートとジェネレータ ができました。
Cheat Sheet
現時点では、PotLite.js のぶんです。 他のライブラリのチートシートを参考にしながら作ってたのですが、 Pot.js のほうはまだリファレンスも全部書けてないので 重要な非同期系の関数/メソッド/プロパティに絞ってたら PotLite.js と同じになりました。 はじめからそうしてればよかった。。
Pot.js (PotLite.js) チートシートとジェネレータ
Cheat Sheet Generator
自分で関数の存在を忘れてしまうことがあって それもどうかと思うので、忘れないように壁紙にできたらなぁて思って せっかくだからいつも使ってる壁紙とか好きな画像とアルファ合成できたらいいなって ジェネレータ作ってみました。 canvas で DataURI にして合成してるだけですが…。(なので Firefox, GoogleChrome, Safari? 限定) 上のリンクからジェネレータのページに行って、 デスクトップとかからブラウザに画像ドロップして合成・生成できます。 ※ソースでも確認できますが画像とかをどっかに送信したり保存したりしてません 通常のチートシートは Basic Cheat Sheet のをダウンロードして利用できます。
Tumblr media
ジェネレータはこんな感じで背景と合成できます。
以下、Pot.js についてのリンクとか。
Pot.js / PotLite.js
Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。 PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。 ダウンロード
Pot.js / PotLite.js 最新
マニュアル
Pot.js + PotLite.js - Document and Reference - JavaScript Async Utility Library
その他の情報についてはマニュアル/リンク から参照ください。
レポジトリ
polygonplanet/Pot.js - GitHub
その他、なにか問題・バグ・感想・指摘などあれば、 コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。
body div.pot-overlay-content { line-height: 1.4; } .pot-overlay-content h2 { font-size: 150%; margin-top: 38px; margin-bottom: 30px; } dl dt { font-style: normal; font-weight: bold; } body div.pot-separator-image, body div.pot-separator-image-full { display: block; margin: 10px; padding: 0; text-align: left; } body div.pot-separator-image a, body div.pot-separator-image-full a { margin-left: 1em; margin-right: 1em; } body div.pot-separator-image a img, body div.pot-separator-image-full a img { border: 2px solid #999; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } body div.pot-separator-image a img.notify, body div.pot-separator-image-full a img.notify { border: 0 none; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; } body div.pot-separator-image a img.portrait, body div.pot-separator-image-full a img.portrait { border: 1px solid #666; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; } body div.pot-overlay-content div.pot-separator-image-full { padding-left: 0 !important; padding-right: 0; margin-left: 0 !important; margin-right: 0; } body div.pot-overlay-content div.pot-separator-image-full a { margin-left: 0; margin-right: 0; }
6 notes · View notes
potjs · 13 years ago
Text
並列処理のWorkerぽいWorkeroid実装。JavaScriptライブラリPot.js 1.17 リリース
Pot.js 1.17 と PotLite.js 1.34 リリースしました。
Web Workers
バックグラウンド処理、並列処理ができる HTML5 API の Web Workers は、 主要なブラウザですでに実装されています。
var worker = new Worker('child.js'); worker.onmessage = function(event) { alert(event.data); // 'hogefuga' がアラートされる }; worker.postMessage('hoge');
child.js
onmessage = function(event) { postMessage(event.data + 'fuga'); };
上のような感じで使うのですが、基本的に 'child.js' のようにファイル名を渡さないといけないんです。 なので JavaScript が 2 ファイルになります。 並列で 4 スレッドとか 6 スレッドとかしてたら どんどん増えてファイルの管理がめんどいです。 あと、ブラウザによって動作 (子Worker のスコープ) が若干異なっていて せっかく並列処理がネイティブにできるのに、なかなか扱いにくいものになってしまってます。 そこで、ネイティブ Worker が利用できたら ネイティブで なければ Worker エミュレータとして、 クロスブラウザに動作する Workeroid (Pot.Workeroid) を実装しました。
Pot.Workeroid
基本的にネイティブ Worker と同じに並列処理ができる
ネイティブ Worker がなければエミュレートする
クロスブラウザ
子 Worker スレッドで importScripts しなくても Pot.js が使える
エミュレート時でも terminate で中断/終了できる
ファイル名だけじゃなく関数オブジェクトを子 Workerとして渡せる
ネイティブの Worker は 子Worker プロセス内では 親 window のライブラリなどが使えません。 importScripts('hoge.js') で読み込まないと使えないのですが、 Pot.Workeroid はデフォルトで Pot.js が利用できます。 なので、Pot.Deferred.forEach などを利用して CPU 負荷を抑えた処理が可能です。 最大の特徴として、 コンストラクタに ファイル名のほか、関数を渡すことが可能なことです。 以下は function で Worker スレッドを生成する例です。 .pot-workeroid-thread { background: #ffe2ef; margin: 0; padding: 5px; *padding: 0; line-height: 1; }
var worker = new Pot.Workeroid(function(data) { // // このスコープの中が 子Worker スレッド // var add = 1; postMessage(data + add); }); // メッセージを受信した時 worker.onmessage = function(data) { alert(data); }; // エラー時の設定 (任意) worker.onerror = function(err) { alert(err); }; // 1 を 子 Worker に送信 => 2 が alert される worker.postMessage(1);
色 をつけたスコープ内が 子 Worker として別スレッドになります。 子 Worker 空間内は、別ファイルに書いてる気持ちでコーディングするとわかりやすいかもです。 たくさんのスレッド作る場合でも、少しの短いコードでも 別ファイルにしなくて済みます。 これで楽に並列処理ができるとうれしい! Pot.Workeroid の例を含む詳細は Pot.Workeroid リファレンス から参照できます。 あと、簡単な動作テスト��� jsFiddle に置いてあります。
http://jsfiddle.net/polygonplanet/ZdHLv/
更新したところ
Pot.Workeroid 実装: Workeroid リファレンス
'just now' とか 'an hour ago' 表記の Pot.DateTime.prettyDate 実装
Pot.tokenize と Pot.joinTokens などのトークナイザ系関数の実装
あとちょっとした最適化とか
Pot.js / PotLite.js
Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。 PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。 ダウンロード
Pot.js / PotLite.js 最新
マニュアル
Pot.js + PotLite.js - Document and Reference - JavaScript Async Utility Library
その他の情報についてはマニュアル/マニュアルからのリンク から参照ください。
レポジトリ
polygonplanet/Pot.js - GitHub
その他、なにか問題・バグ・感想・指摘などあれば、 コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。
body div.pot-overlay-content { line-height: 1.4; } .pot-overlay-content h2 { font-size: 150%; margin-top: 38px; margin-bottom: 30px; } dl dt { font-style: normal; font-weight: bold; } body div.pot-separator-image, body div.pot-separator-image-full { display: block; margin: 10px; padding: 0; text-align: left; } body div.pot-separator-image a, body div.pot-separator-image-full a { margin-left: 1em; margin-right: 1em; } body div.pot-separator-image a img, body div.pot-separator-image-full a img { border: 2px solid #999; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } body div.pot-separator-image a img.notify, body div.pot-separator-image-full a img.notify { border: 0 none; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; } body div.pot-separator-image a img.portrait, body div.pot-separator-image-full a img.portrait { border: 1px solid #666; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; } body div.pot-overlay-content div.pot-separator-image-full { padding-left: 0 !important; padding-right: 0; margin-left: 0 !important; margin-right: 0; } body div.pot-overlay-content div.pot-separator-image-full a { margin-left: 0; margin-right: 0; }
0 notes
potjs · 13 years ago
Text
jsFiddleだらけ-JavaScriptライブラリPot.js+PotLite.jsリリースノート
Pot.js 1.15 1.16 と PotLite.js 1.32 1.33 リリースしました。
2012-03-13 追記: Pot.js 1.15 と PotLite.js 1.33 はバギーなためアップデートしました。詳細 2012-03-13 時点の最新は Pot.js 1.16 と PotLite.js 1.34 です。最新にアップデートお願いします。。
このバージョンでは、
文字列処理の高速化
重くなりそうな処理を非同期化
などを適応しました。
文字列処理の高速化
先日、ふと思って String.fromCharCode を呼ばずに U+0000 - U+FFFF の配列をあらかじめ作成して インデックスに対応させたらどうなのかなって ベンチマークとってみました。
http://jsfiddle.net/polygonplanet/Ap6st/
結果として、String.fromCharCode(c) のような apply で配列を使わない場合、かなり高速化できました。 メモリ消費も文字列などは気にするほどじゃなかった。 String.fromCharCode.apply(null, [...]); のような場合は逆に遅くなるので 従来通り String.fromCharCode を使用しています。 (この件はあほなミスをしてて@gochoさんにつっこまれて助かりました)
重くなりそうな処理を非同期化
重くなりそうな処理とは、巨大な文字列が渡される可能性のある関数や、 ループ回数が未知の処理などです。 途中で「応答のないスクリプト」警告なんぞ でてしまったらめんどうです。 そういった対処や負荷軽減も含めて 関数オブジェクトに deferred というメソッドを持たせました。 例えば Pot.md5(string); が同期実行に対して Pot.md5.deferred(string); は、非同期で実行します。
Pot.md5 非同期実行のサンプル:
http://jsfiddle.net/polygonplanet/6e2E5/
圧縮・解凍
文字列を LZ77 アルゴリズムをベースに圧縮・解凍する Pot.Archive.AlphamericString も同様に非同期化しています。
Pot.Archive.AlphamericString 非同期実行のサンプル:
http://jsfiddle.net/polygonplanet/aT3hT/
Pot.Archive.AlphamericString のリファレンス
その他のサンプル
他にもいくつかテスト用にサンプルがあったので紹介します。
HTML の適した場所に を挿入する Pot.br() :
http://jsfiddle.net/polygonplanet/78Q7d/
Pot.br のリファレンス
文字列の置換代行 :
http://jsfiddle.net/polygonplanet/RExAS/
Pot.js / PotLite.js
Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。 PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。 ダウンロード
Pot.js / PotLite.js 最新
マニュアル
Pot.js + PotLite.js - Document and Reference - JavaScript Async Utility Library
その他の情報についてはマニュアル/マニュアルからのリンク から参照ください。
レポジトリ
polygonplanet/Pot.js - GitHub
その他、なにか問題・バグ・感想・指摘などあれば、 コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。
body div.pot-overlay-content { line-height: 1.4;}.pot-overlay-content h2 {font-size: 150%; margin-top: 38px; margin-bottom: 30px;}dl dt {font-style:normal; font-weight: bold;}body div.pot-separator-image,body div.pot-separator-image-full { display: block; margin: 10px; padding: 0pt; text-align: left;}body div.pot-separator-image a,body div.pot-separator-image-full a {margin-left: 1em; margin-right: 1em;}body div.pot-separator-image a img,body div.pot-separator-image-full a img { border: 2px solid #999;border-radius:3px; -moz-border-radius:3px;-webkit-border-radius:3px;}body div.pot-separator-image a img.notify,body div.pot-separator-image-full a img.notify { border: 0 none; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset;}body div.pot-separator-image a img.portrait,body div.pot-separator-image-full a img.portrait { border: 1px solid #666; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset;}body div.pot-overlay-content div.pot-separator-image-full { padding-left: 0 !important; padding-right: 0; margin-left: 0 !important; margin-right: 0;}body div.pot-overlay-content div.pot-separator-image-full a {margin-left: 0; margin-right: 0;}
2 notes · View notes
potjs · 13 years ago
Text
同期処理を非同期に変換-JavaScriptライブラリPot.js+PotLite.jsリリースノート
Pot.js 1.14 と PotLite.js 1.31 リリースしました。 その前に Pot.js + PotLite.js リファレンス が完成しました (ということにしたい) ので、 お時間あるときにでも覗いてみてください。 結局 /test-for-new-design/ に置いてあるのはファイル消すのも嫌だし 全部リダイレクトさせるようにしました。 Pot.js 1.14 と PotLite.js 1.31 では、Pot.deferreed() ていう関数つくりました。 deferreed は、関数の中の for, for-in, for-of, do, while 等の同期ループを Pot.Deferred.forEach() などの非同期イテレータに置き換えて関数を再定義します。 前の記事「JavaScript whileループとPot.Deferred.forEverイテレータでCPU使用率を比較」 でも書いてますが、 Pot.js ライブラリのイテレータは CPU の負荷なく実行できます。 ループを置き換えることで、巨大な文字列を扱ったり、ループ回数が未知な処理をする際に 重さについて考えなくて済むようにと、作ってみまみた。 もともとは deferrize() という関数から派生しています。 関数内のコードをトークン単位に分解して、 単純にトークンの数が多いループブロックをメインループとして解析して、 その文に見合った Pot.Deferred イテレータを割り当ててるんですが ぜんぜん思ったよりたいへんで まだ複雑なものは対応できてないです。 とくに三項演算子 (?:) と function のコンボとか、E4X とかまでは今後の課題。。 にしたいけど、 そこまでしてたらライブラリの方向性違うんじゃないの��て思ってしかたないです。 deferreed の 1 コールで zip.deflate 圧縮とかファイル規模への md5 とか非同期化できたら楽そう。
例えば以下のような関数が
// 文字列を charCode からなる配列にして返す関数 var toCharCode = function(string) { var result = []; for (var i = 0; i < string.length; i++) { result.push(string.charCodeAt(i)); } return result; }; // deferreed により for 文を非同期イテレータにした関数を生成 var toCharCodeDefer = Pot.deferreed(toCharCode); // 例えば toCharCodeDefer は内部で以下のような感じに変換される // // function(string) { // var result = []; // return Pot.Deferred.repeat(string.length, function(i) { // result.push(string.charCodeAt(i)); // }).then(function() { // return result; // }); // }; // // Pot.Deferred インスタンスが返るため then() などで繋げられる toCharCodeDefer('abc').then(function(res) { Pot.debug(res); // [97, 98, 99] }); // この変化により、巨大な文字列でも負荷を分散させ実行できる var largeString = new Array(100000).join('abcdef'); // 'slow' などの指定が可能 toCharCodeDefer.slow(largeString).then(function(res) { Pot.debug(res.length); // 599994 });
あと、プラグインみたいなことしたくて Pot.Plugin ての作ったんですが なにか違うような気がしてならないです。 プラグイン = ただのオブジェクト になってしまった。 Pot.addPlugin() という関数で任意の関数とかオブジェクトを登録。 Pot.removePlugin() で削除。 Pot.hasPlugin() で確認、Pot.listPlugin() で列挙。 addPlugin した関数は Pot.xxx でアクセスできる。 ・・・それって Pot.myFunc = function() {}; でいいじゃん! てなったので、 以下のようにしてみました。
var string = '\t abc\n \t '; // オリジナルの Pot.trim() debug(Pot.trim(string)); // 'abc' // プラグイン関数の登録により Pot.trim() を上書き Pot.addPlugin('trim', function(s) { return s.replace(/^ +| +$/g, ''); // スペース (U+0020) だけ削除するようにする }); // 登録した Pot.trim() debug(Pot.trim(string)); // '\t abc\n \t' // プラグインの trim を削除 Pot.removePlugin('trim'); // 元に戻る debug(Pot.trim(string)); // 'abc'
元に戻せる (むしろ消えない) ので、 一時的に挙動を変えたい時とか便利かもしれないです。 あと、Pot.globalize() したときに プラグイン関数もグローバル化します。 Pot.globalize() しなくても with (Pot) {...} でもいい気がしてきました。 プラグインの詳細は Pot.Plugin リファレンス あたりから参照ください。 マニュアルは英語版も含めてちょっとずつ進めています。
以下はレポジトリとかのリンクなど。
Pot.js / PotLite.js
Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。 PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。 ダウンロード
Pot.js / PotLite.js 最新
マニュアル
Pot.js + PotLite.js - Document and Reference - JavaScript Async Utility Library
その他の情報についてはマニュアル/マニュアルからのリンク から参照ください。
レポジトリ
polygonplanet/Pot.js - GitHub
その他、なにか問題・バグ・感想・指摘などあれば、 コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。
body div.pot-overlay-content { line-height: 1.4;}.pot-overlay-content h2 {font-size: 150%; margin-top: 38px; margin-bottom: 30px;}dl dt {font-style:normal; font-weight: bold;}body div.pot-separator-image,body div.pot-separator-image-full { display: block; margin: 10px; padding: 0pt; text-align: left;}body div.pot-separator-image a,body div.pot-separator-image-full a {margin-left: 1em; margin-right: 1em;}body div.pot-separator-image a img,body div.pot-separator-image-full a img { border: 2px solid #999;border-radius:3px; -moz-border-radius:3px;-webkit-border-radius:3px;}body div.pot-separator-image a img.notify,body div.pot-separator-image-full a img.notify { border: 0 none; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset;}body div.pot-separator-image a img.portrait,body div.pot-separator-image-full a img.portrait { border: 1px solid #666; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset;}body div.pot-overlay-content div.pot-separator-image-full { padding-left: 0 !important; padding-right: 0; margin-left: 0 !important; margin-right: 0;}body div.pot-overlay-content div.pot-separator-image-full a {margin-left: 0; margin-right: 0;}
1 note · View note
potjs · 13 years ago
Text
JavaScript whileループとPot.Deferred.forEverイテレータでCPU使用率を比較-Pot.js+PotLite.jsリリースノート
Pot.js 1.13 と PotLite.js 1.30 リリースしました。 Pot.js 1.13 と PotLite.js 1.30 では、主に内部ループ処理を大幅に高速化しました。 (そろそろ ChangeLog 作らないとまずいかも…) あとは、変数宣言とか 例の (function(){}()) とか (結局直してる) 細かい修正などです。 先日、Hacker News や Echo JS で Pot.js が紹介されました (ありがとうございます)。 でもアクセスが今までの 1000 倍くらいになって、すごいことになってちょっとビビった。 (API サーバのほうは適当に調節しておいたので大丈夫だった。よかった。。) それで Pot.js の本来の存在意義ですが、 実行環境の CPU に負荷をかけることなく JavaScript が実行できる。 といったことが本来の目的であり、常に追求している目標でもあります。 Deferred が重点にとらわれがちですが、Pot.Deferred はそれの足がかりであり、 Pot.Deferred だけがライブラリの中核ではないので、いろいろ使ってみてください。
新しいデザインのリファレンス
現在、新しいデザインでリファレンスを書き直しています。
Pot.js + PotLite.js - Document and Reference - JavaScript Async + String Utility Library
前は 全部で 1 ファイルになっちゃってて、どんどん重くなるし更新もやり難くて どうしようもなかったのですが、今回は 各ページを非同期読み込みにして 英語版と日本語版で見れるようにして、戻るボタンとかも再現したり、がんばってます。 でもまだ作成途中です (2012-02-11 現在)。 ある程度完成したら 本来の /index.html に移動させようと思ってるんですが、 先ほどの Echo JS などが /test-for-new-design/ にリンクしちゃってるもんだから どうしようかと考え中。(たぶん リダイレクトか、もうこのままでいいか…)。
CPU 比較を実行
jsFiddle のほうで JavaScript の while ループと、Pot.js の非同期イテレータとで CPU 使用率の比較を書いてみました。 前に書いた Pot.js イテレータと jQuery.each と for ループの CPU 使用率をグラフで比較 と同じ事ですが、実際に実行できます (ただし負荷テストなのでブラウザクラッシュに気をつけてください)。 もっとも最近のブラウザはループでクラッシュしないと思いますが。。 CPU 使用率は、Web ブラウザからの JavaScript では取得できないと思うので、 CPU モニタリングするアプリとか、 なければ Win ならタスクマネージャから「パフォーマンス」→ 「CPU 使用率」 を見ながら実行してみるとわかりやすいと思います。
JavaScript while ループと Pot.Deferred.forEver イテレータの CPU 使用率を比較 - jsFiddle
今回は while 文と Pot.Deferred.forEver の比較ですが、 Pot.js 非同期イテレータは CPU 負荷が一定量に抑えられたループが可能になっていると思います。 ただし、この例のような処理だと実行時間はある程度伸びてしまいます。 実行時間に関しては 速度調整 が可能なので、処理に応じたスピードを選ぶこともできます。 (このへんは今後改善したいです)。
サンプルのソースコード
jsFiddle でも確認できますが、今回使用したサンプルのソースコードです。 ループ処理の部分だけ抽出しています。 JavaScript while ループを使ったソースコード:
// while で同期ループして圧縮 compressSync : function(s) { var a = 53300, b, c, d, e, f, g = -1, h, i, r = [], x = String.fromCharCode; s = new Array(a--).join(' ') + s; while ((b = s.substr(a, 256))) { for (c = 2, i = b.length; c <= i; ++c) { d = s.substring( a - 52275, a + c - 1 ).lastIndexOf(b.substring(0, c)); if (!~d) { break; } e = d; } if (c === 2 || c === 3 && f === g) { f = g; h = s.charCodeAt(a++); r.push( x(h >> 8 & 255), x(h & 255) ); } else { r.push( x((e >> 8 & 255) | 65280), x(e & 255), x(c - 3) ); a += c - 1; } } return r.join(''); }
Pot.js 非同期イテレータ (今回は Pot.Deferred.forEver) を使ったソースコード:
// Pot.js 非同期イテレータで圧縮 compressAsync : function(s) { var a = 53300, b, c, d, e, f, g = -1, h, i, r = [], x = String.fromCharCode; var deferred = new Pot.Deferred(); s = new Array(a--).join(' ') + s; // whileループを forEver に置き換え Pot.Deferred.forEver[SPEED](function() { b = s.substr(a, 256); if (!b) { throw Pot.StopIteration; } for (c = 2, i = b.length; c <= i; ++c) { d = s.substring( a - 52275, a + c - 1 ).lastIndexOf(b.substring(0, c)); if (!~d) { break; } e = d; } if (c === 2 || c === 3 && f === g) { f = g; h = s.charCodeAt(a++); r.push( x(h >> 8 & 255), x(h & 255) ); } else { r.push( x((e >> 8 & 255) | 65280), x(e & 255), x(c - 3) ); a += c - 1; } }).then(function() { deferred.begin(r.join('')); }, function(err) { deferred.raise(err); }); return deferred; }
同期か非同期かの違いがありますが、 単に、メインの while 文を Pot.Deferred.forEver に変えてるだけです。 forEver は、StopIteration が throw されるまで、永久にループする関数です。 あと、この関数は LZ77アルゴリズムによる圧縮関数をJavaScript最短コードで | 圧縮電子精神音楽浮遊構造体 (見れないかも) で作ったソースコードをちょっとだけ手直ししたものです。 文字列を圧縮解凍します。
Pot.js / PotLite.js
Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。 PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。 ダウンロード
Pot.js / PotLite.js 最新
マニュアル
Pot.js + PotLite.js - Document and Reference - JavaScript Async + String Utility Library (作成中)
Pot.js + PotLite.js ドキュメント リファレンス
マニュアルは上に書いたように 2012-02-11 現在、まだすべてのオブジェクトの解説ができてません。。 その他の情報についてはマニュアル/マニュアルからのリンク から参照ください。
レポジトリ
polygonplanet/Pot.js - GitHub
その他、なにか問題・バグ・感想・指摘などあれば、 コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。
body div.pot-overlay-content { line-height: 1.4;}.pot-overlay-content h2 {font-size: 150%; margin-top: 38px; margin-bottom: 30px;}dl dt {font-style:normal; font-weight: bold;}body div.pot-separator-image,body div.pot-separator-image-full { display: block; margin: 10px; padding: 0pt; text-align: left;}body div.pot-separator-image a,body div.pot-separator-image-full a {margin-left: 1em; margin-right: 1em;}body div.pot-separator-image a img,body div.pot-separator-image-full a img { border: 2px solid #999;border-radius:3px; -moz-border-radius:3px;-webkit-border-radius:3px;}body div.pot-separator-image a img.notify,body div.pot-separator-image-full a img.notify { border: 0 none; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset;}body div.pot-separator-image a img.portrait,body div.pot-separator-image-full a img.portrait { border: 1px solid #666; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset;}body div.pot-overlay-content div.pot-separator-image-full { padding-left: 0 !important; padding-right: 0; margin-left: 0 !important; margin-right: 0;}body div.pot-overlay-content div.pot-separator-image-full a {margin-left: 0; margin-right: 0;}
0 notes
potjs · 13 years ago
Text
HTML5 File APIでドラッグ&ドロップのサンプル-Pot.js+PotLite.jsリリースノート
Pot.js 1.11 と PotLite.js 1.28 リリースしました。 主な新機能として、HTML5 の File API を使った ファイルのドラッグ&ドロップ を扱う Pot.DropFile を実装しました。 Pot.DropFile は FileReader でドロップされたファイルをアップロードしたり 内容やサイズを取得してその場で処理することが可能です。
Tumblr media
HTML5 とドラッグ&ドロップイベントをサポートしてるブラウザ (Firefox, GoogleChrome, Safari) で このブログ内に、デスクトップなどから画像やテキストなどの適当なファイルをドロップしてみてください。
ここにドロップされたファイル内容が表示されます。
$(function () { // ドロップされた結果を表示する div var targetId = '#dropfile-container'; // ドロップ用のパネルを作成 var panel = $('<div/>').css({ position : 'fixed', left : '10%', top : '10%', width : '80%', height : '80%', minHeight : 200, background : '#ff8cd3', zIndex : 9999999, display : 'table', textAlign : 'center', WebkitBoxShadow : '1px 1px 10px #333', MozBoxShadow : '1px 1px 10px #333', boxShadow : '1px 1px 10px #333' }) .append( $('<div/>') .css({ display : 'table-cell', color : '#fff', fontWeight : 'bold', verticalAlign : 'middle', fontSize : '160%' }) .text('ここにファイルをドロップします') ) .hide() .appendTo('body'); // ファイルの情報を表示する関数 var showFileInfo = function(name, size, type) { $('<div/>') .text(name + ' (' + type + ' ' + size + 'bytes)') .appendTo(targetId); }; // ----- ここから処理の中心 ----- // 設定と共にインスタンスを生成 var dropFile = new Pot.DropFile(panel, { // メッセージを表示すべき時 onShow : function() { panel.show() }, // メッセージを非表示にすべき時 onHide : function() { panel.hide() }, // ドロップ時の処理 onDrop : function(files) {}, // 画像がドロップされた時 onLoadImage : function(data, name, size, type) { showFileInfo(name, size, type); $('<img/>') .attr({src : data}) .css({maxWidth : 500, maxHeight : 500}) .appendTo(targetId); }, // テキストがドロップされた時 onLoadText : function(data, name, size, type) { showFileInfo(name, size, type); $('<textarea/>') .val(data) .css({width : '90%', height : 300}) .appendTo(targetId); }, // 不明なファイルがドロップされた時 onLoadUnknown : function(data, name, size, type) { showFileInfo(name, size, type); $('<textarea/>') .val(data) .css({width : '90%', height : 300}) .appendTo(targetId); }, // ドロップされたファイルが読み込めた時 (このときアップロードも可能) onLoadEnd : function(files) { // 今回は未使用 /* this.upload( 'http://www.example.com/', 'dropfiles' ).then(function(res) { alert('finish upload.\nresponse:\n\n' + res.responseText); }); */ } }); });
ソースコード
このサンプルのソースコードです。 DOM ノードを作成するのにあたって jQuery を使用しています。 HTML のソース:
<div id="dropfile-container" style="border-color: #ccc; border-style: dashed; border-width: 1px 0 1px 0; margin: 10px;"> ここにドロップされたファイル内容が表示されます。 </div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="http://api.polygonpla.net/js/pot/1.11/pot.min.js"></script>
JavaScript のソース:
$(function () { // ドロップされた結果を表示する div var targetId = '#dropfile-container'; // ドロップ用のパネルを作成 var panel = $('<div/>').css({ position : 'fixed', left : '10%', top : '10%', width : '80%', height : '80%', minHeight : 200, background : '#ff8cd3', zIndex : 9999999, display : 'table', textAlign : 'center', WebkitBoxShadow : '1px 1px 10px #333', MozBoxShadow : '1px 1px 10px #333', boxShadow : '1px 1px 10px #333' }) .append( $('<div/>') .css({ display : 'table-cell', color : '#fff', fontWeight : 'bold', verticalAlign : 'middle', fontSize : '160%' }) .text('ここにファイルをドロップします') ) .hide() .appendTo('body'); // ファイルの情報を表示する関数 var showFileInfo = function(name, size, type) { $('<div/>') .text(name + ' (' + type + ' ' + size + 'bytes)') .appendTo(targetId); }; // ----- ここから処理の中心 ----- // 設定と共にインスタンスを生成 var dropFile = new Pot.DropFile(panel, { // メッセージを表示すべき時 onShow : function() { panel.show() }, // メッセージを非表示にすべき時 onHide : function() { panel.hide() }, // ドロップ時の処理 onDrop : function(files) {}, // 画像がドロップされた時 onLoadImage : function(data, name, size, type) { showFileInfo(name, size, type); $('<img/>') .attr({src : data}) .css({maxWidth : 500, maxHeight : 500}) .appendTo(targetId); }, // テキストがドロップされた時 onLoadText : function(data, name, size, type) { showFileInfo(name, size, type); $('<textarea/>') .val(data) .css({width : '90%', height : 300}) .appendTo(targetId); }, // 不明なファイルがドロップされた時 onLoadUnknown : function(data, name, size, type) { showFileInfo(name, size, type); $('<textarea/>') .val(data) .css({width : '90%', height : 300}) .appendTo(targetId); }, // ドロップされたファイルが読み込めた時 (このときアップロードも可能) onLoadEnd : function(files) { // 今回は未使用 /* this.upload( 'http://www.example.com/', 'dropfiles' ).then(function(res) { alert('finish upload.\nresponse:\n\n' + res.responseText); }); */ } }); });
Pot.js / PotLite.js
Pot.js は非同期イテレータと文字列処理を中心とした JavaScript ライブラリです。 Web ブラウザ上や Node.js 上、 UserScript や XUL 上で動作します。 この例のような DOM や HTML5 File API が含む処理は Node.js などの環境では意味がありませんが テキスト処理やイテレータなどを利用するメリットがあります。 とくに非同期処理を扱う Deferred オブジェクトにより作業効率が向上すると思います。 PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。 ダウンロード
Pot.js / PotLite.js 最新
マニュアル
Pot.js + PotLite.js ドキュメント リファレンス
マニュアルは 2012-01-11 現在、まだすべてのオブジェクトの解説ができてません。。 その他の情報についてはマニュアルから参照ください。
レポジトリ
polygonplanet/Pot.js - GitHub
body div.pot-overlay-content { line-height: 1.4;}.pot-overlay-content h2 {font-size: 150%; margin-top: 38px; margin-bottom: 30px;}dl dt {font-style:normal; font-weight: bold;} body div.pot-separator-image,body div.pot-separator-image-full { display: block; margin: 10px; padding: 0pt; text-align: left;} body div.pot-separator-image a,body div.pot-separator-image-full a {margin-left: 1em; margin-right: 1em;} body div.pot-separator-image a img,body div.pot-separator-image-full a img { border: 2px solid #999;border-radius:3px; -moz-border-radius:3px;-webkit-border-radius:3px;} body div.pot-separator-image a img.notify,body div.pot-separator-image-full a img.notify { border: 0 none; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset;} body div.pot-separator-image a img.portrait,body div.pot-separator-image-full a img.portrait { border: 1px solid #666; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; } body div.pot-overlay-content div.pot-separator-image-full { padding-left: 0 !important; padding-right: 0; margin-left: 0 !important; margin-right: 0; } body div.pot-overlay-content div.pot-separator-image-full a {margin-left: 0; margin-right: 0;}
0 notes
potjs · 13 years ago
Text
JavaScript非同期ライブラリ PotLite.js 1.23 リリース
JavaScript 非同期処理ライブラリ PotLite.js 1.23 リリースしました。 Version 1.23 は、ほとんどバグフィックスです。 AOP ぽいことができる Pot.Signal がひどくて、 シグナル解除して再度登録すると重複してコールバック関数が呼ばれちゃったりしてたので がんばって可能な限り実行テスト増やしてフィックスして やっと想定の動きになりました。 前バージョン (1.22) を使ってる方いたら申し訳ないです。。
PotLite.js
PotLite.js は、めんどうになりがちな非同期処理をとにかく楽にコーディングできるよう 直感的に記述できる Deferred オブジェクトを中核として実装しています。 そして、ユーザー (UI) への配慮を目的として CPU など負荷のかからないループ処理やイテレータが利用できる JavaScript ライブラリです。 経緯などについては、以前の記事 や、 CPU 使用率のベンチマーク結果の記事 など シグナル (イベント) については PotLite.js 1.22 リリース - アスペクト指向っぽく書けるSignal実装 などの記事を参照ください。
ダウンロード
PotLite.js 1.23
zip
tar.gz
HEAD (常に最新)
zip
tar.gz
レポジトリ
$ git clone git://github.com/polygonplanet/Pot.js
polygonplanet/Pot.js - GitHub
以下は PotLite.js について情報です。 レポジトリにも同じようなこと書いてあるので インストールや概要など、不要な場合は読み飛ばしてください。 マニュアルのリンクは下にあります。
動作環境
以下の Web ブラウザで動作確認済みです。
Mozilla Firefox *
Internet Explorer 6+
Safari *
Opera *
Google Chrome *
また、以下の環境でも動作するよう設計され��います。
Greasemonkey (UserScript)
Mozilla Firefox Add-On (on XUL)
Node.js
Other non-browser environment
インストール
一般的な方法で動作します。
例:
<script type="text/javascript" src="potlite.min.js"></script> <!--または--> <script type="text/javascript" src="http://api.polygonpla.net/js/pot/potlite/1.23/potlite.min.js"></script>
Node.js の場合。
// Example to define Pot object on Node.js. var Pot = require('./potlite.min.js'); Pot.debug(Pot.VERSION); Pot.Deferred.begin(function() { Pot.debug('Hello Deferred!'); }).then(function() { // ... }); // ...
Greasemonkey (userscript) の例。
// ==UserScript== // ... // @require https://github.com/polygonplanet/Pot.js/raw/master/potlite.min.js // ... // ==/UserScript== Pot.Deferred.begin(function() { return Pot.request('http://www.example.com/data.json').then(function(res) { return Pot.parseFromJSON(res.responseText); }); }).then(function(res) { Pot.debug(res); // do something... }); //...
PotLite.js をバージョンを限定して Web から直接読み込みたい場合、 上の GitHub リンクでは常に最新になってしまうため 実装の差異による不具合が発生するかもしれません。 そのため、ホスティング用 API サーバを用意しています。
v1.23 : http://api.polygonpla.net/js/pot/potlite/1.23/potlite.min.js
これは、1.23 の部分をリリース済みのバージョンに合わせて変更できます。 レポジトリに (例えば 1.xx と) バージョンをタグ付けした時に、 あわせて API サーバに置くようにしています。 例えば Greasemonkey で 1.23 を使いたい場合、
// ==UserScript== // ... // @require http://api.polygonpla.net/js/pot/potlite/1.23/potlite.min.js // ... // ==/UserScript==
と記述できます。 Greasemonkey に限らず script タグからでもなんでも自由に使ってください。
jQuery プラグインとしての例:
// jQuery を読み込んだ後に実行。 Pot.deferrizejQueryAjax(); // Ajax 系の関数が Pot.Deferred を返すようになる $.getJSON('/hoge.json').then(function(data) { alert(data.results[0].text); }).rescue(function(err) { alert('Error! ' + err); }).ensure(function() { return someNextProcess(); }); // エフェクトなどを Deferred 化する 'deferred' が追加される $('div#hoge').deferred('hide', 'slow').then(function() { // .hide() が終了したあとの処理 });
Pot.deferrizejQueryAjax() は v1.23 現在、ライブラリ側からは自動で実行しません。 なので、プラグインとして利用する場合は コードの最初などで一度コールしてください。
リファレンス・マニュアル
より詳しい情報はすべてリファレンスに載っています。 基本的な導入や、各メソッド・関数についても扱っています。
Pot.js + PotLite.js - ドキュメントリファレンス - JavaScript非同期処理ライブラリ
動作テスト
以下のページで動作テストができます。 ページを開くと実装されている主な関数・メソッドを全てテストします。
Pot.js + PotLite.js - Test Run - JavaScript Async Library
自動生成されたドキュメント
JSDoc ドキュメント (PotLite.js)
Closure Compiler によりソースコードから自動生成されたドキュメントです。
殆どの関数ごとにサンプルコードを載せているので、ある程度は参考になると思います。 生成物をすべて確認しているわけではないので、誤認識してる箇所もあるかもしれません。 より詳細な実装などは直接ソースコードを参照ください。
不明な点、要望やバグや感想などありましたら @polygon_planet や 下のレポジトリから、またはメールでなんでも伝えてください。
レポジトリ
polygonplanet/Pot.js - GitHub
0 notes
potjs · 13 years ago
Text
JavaScript非同期ライブラリ PotLite.js 1.22 リリース。アスペクト指向っぽく書けるSignal実装
追記
PotLite.js 1.22 はバギーなため 記事内のリンクを 1.23 に変更しました。
PotLite.js 1.22 リリースしました。 PotLite.js は、非同期処理や負荷のかからないループ処理やイテレータを重視した JavaScript ライブラリです。 経緯などについては、以前の記事 や、 CPU 使用率のベンチマーク結果の記事 を参照ください。
ダウンロード
PotLite.js 最新
zip
tar.gz
レポジトリ
polygonplanet/Pot.js - GitHub
PotLite.js バージョン 1.22 では Pot.Signal オブジェクトを実装しました。 Pot.Signal は、任意のハンドラを登録し シグナルを送信して実行に移すことが可能です。 言い方を変えると、自らイベントを作成し、任意のタイミングで呼び出せるようなものです。 「イベント」という概念で実装したわけではありませんが、ここでは便宜上イベントという言い方をします。 Pot.Signal には大まかに以下の関数があります。
attach : イベントを登録
detach : イベントを解除
signal : イベントを実行
Pot.Signal の使用例
Pot.Signal はいろいろな使い方があります。 例えば、
// イベントを登録 // (第一引数に文字列を渡すと document.getElementById を使用する) var handler = attach('#foo', 'click', function(ev) {...}); // イベント解除 detach(handler);
上のように addEventListener/removeEventListener の代わりに使用したり、
var MyObj = {}; // 独自のシグナルを登録 var handler = attach(MyObj, 'clear-data', function() { // プロパティの初期化など MyObj.data = null; MyObj.time = null; }); attach(window, 'load', function() { // 初期化するシグナルを送信 signal(MyObj, 'clear-data'); // リセットボタンを押した時にもクリアするよう設定 attach('#reset', 'click', function() { signal(MyObj, 'clear-data'); }); // 既存の処理など myLoadProcess(); //... });
上のように attach, signal を独自のシグナルとして使用したりできます。 そして、attachBefore と attachAfter を使うと処理の前後に何らかの動作を追加できます。
// 保存ボタンを押した時のイベントを設定 attach('#saveData', 'click', function() { // 保存する関数 saveData(document.getElementById('inputText').value); // ユーザーに保存を伝える関数 showSaveData('Saved!'); }); // これにフォーカス移動するよう後付けする attachAfter('#saveData', 'click', function() { document.getElementById('inputText').focus(); }); // その前にログを取るよう設定する attachBefore('#saveData', 'click', function() { MyLogger.log('Save inputText'); });
attachBefore, attachAfter はいくつでも登録できます。 登録した順に実行されます。 また、attachPropBefore, attachPropAfter という関数もあります。 これは、attachBefore, attachAfter と違い、 オブジェクトの関数にダイレクトに作用します。 オブジェクトの持つ関数が呼ばれると、自動的に Before, After のハンドラ関数が実行されます。 例えば何らかのアプリケーションを実行する時に、ログをとりたくなった場合。
var MyApp = { execute : function() { // 何らかの処理を開始する myAppDoit(); } // ... }; attach('#execute', 'click', function() { // アプリケーションを実行 MyApp.execute(); }); // 実行する前にログを取る attachPropBefore(MyApp, 'execute', function() { MyLogger.log('Begin execute'); }); // 実行した後のログを取る attachPropAfter(MyApp, 'execute', function() { MyLogger.log('End execute'); });
このように設定することで、上の例の場合では MyApp.execute が実行される前後に任意の処理を追加できます。 解除したくなったら、
var handler = attach(...); // シグナルを解除 detach(handler);
attach*() 関数の戻り値のハンドラオブジェクトを使い、 detach (Pot.Signal.detach) で解除できます。 他にも detachAll() を使い一括で解除することもできます。 Pot.attach(), Pot.signal() などは Pot.Signal.attach() として実装されていますが、 Pot オブジェクトからも参照できます。 Pot.globalize() を実行しておくと、単に attach(obj, ...) と書けます。 今回の例では attach と表現しています。 これらの関数、とくに Before, After を使うことで、 アスペクト指向 (AOP) っぽいプログラミングが可能となります。 Pot.Signal は Node.js などのサーバでの利用も可能ですが、 Web ブラウザ上、HTML5 での Web Storage (localStorage や sessionStorage) を使う時などに便利と思います。 また、attach 系の関数 (attach*) の後に .once を付けると、一度だけ実行されます。
// 一度クリックしたら解除される attach.once('#hoge', 'click', function() {...});
Pot.Signal の関数
Pot.Signal.attach(object, signalName, callback[, useCapture])
スロットにシグナルを登録します。 Pot.Signal が保持しているハンドラリストに任意のオブジェクトとコールバック関数を登録します。 引数 object が DOM エレメントだった場合、addEventListener と同じように働きます。 戻り値は、Pot.Signal.Handler のインスタンスです。
Pot.Signal.attachBefore(object, signalName, callback[, useCapture])
スロットに存在するハンドラが呼ばれる前に実行されるシグナルを登録します。 Pot.Signal.attach() で登録したものと同じシグナル signalName で登録した場合、 attach() のハンドラが呼ばれる前に実行されます。 同じシグナルが存在しない場合 signal() によって実行しても何も起きません。 DOM エレメントに対して attach() した場合も同様です。 戻り値は、Pot.Signal.Handler のインスタンスです。
Pot.Signal.attachAfter(object, signalName, callback[, useCapture])
スロットに存在するハンドラが呼ばれた後に実行されるシグナルを登録します。 Pot.Signal.attach() で登録したものと同じシグナル signalName で登録した場合、 attach() のハンドラが呼ばれた後に実行されます。 同じシグナルが存在しない場合 signal() によって実行しても何も起きません。 DOM エレメントに対して attach() した場合も同様です。 戻り値は、Pot.Signal.Handler のインスタンスです。
Pot.Signal.attachPropBefore(object, propName, callback)
object が持つ関数 propName が呼ばれる前に実行されるシグナル callback を登録します。 attachBefore() と違い、Pot.Signal.signal() を呼ばなくても object[propName] が呼ばれた時に自動的に実行されます。 attachPropBefore は、DOM オブジェクトに対しての動作は保証されません。 戻り値は、Pot.Signal.Handler のインスタンスです。
Pot.Signal.attachPropAfter(object, propName, callback)
object が持つ関数 propName が呼ばれた後に実行されるシグナル callback を登録します。 attachAfter() と違い、Pot.Signal.signal() を呼ばなくても object[propName] が呼ばれた時に自動的に実行されます。 attachPropAfter は、DOM オブジェクトに対しての動作は保証されません。 戻り値は、Pot.Signal.Handler のインスタンスです。
Pot.Signal.detach(object[, signalName[, callback[, useCapture]]])
Pot.Signal.attach*() によって登録したシグナルを 1 つ解除します。 attachBefore, attachAfter, attachPropBefore, attachPropAfter で登録したものも同様に解除可能です。 引数に object だけを渡した場合、関連するシグナルが 1 つ解除されます。 引数 signalName, callback を渡すと明確に解除できます。 また、attach() などの戻り値のハンドラを object として渡して解除もできます。 登録と解除の関係は、setTimeout と clearTimeout の関係と同様に扱えます。 DOM エレメントに対しては、 removeEventListener と同様に扱うことができます。 解除成功時に true、失敗時に false が返ります。
Pot.Signal.detachAll([object[, ...signals]])
Pot.Signal.attach*() によって登録したシグナルをすべて解除します。 attachBefore, attachAfter, attachPropBefore, attachPropAfter で登録したも���も同様に解除可能です。 引数に object だけを渡した場合、関連するシグナルがすべて解除されます。 引数 signals を渡すと一致するシグナルがすべて解除できます。 シグナル名となる signals は文字列または配列で複数指定できます。
Pot.Signal.signal(object, signalName[, ...args])
Pot.Signal.attach() によって登録したシグナルを実行します。 引数 object と signalName に一致するシグナルがすべて実行されます。 実行される関数には第三引数~以降に任意の引数が渡せます。
PotLite.js
以下は PotLite.js について情報です。 インストールや概要など、不要な場合は読み飛ばしてください。
PotLite.js ダウンロード
最新
zip
tar.gz
レポジトリ
$ git clone git://github.com/polygonplanet/Pot.js
GitHub : polygonplanet/Pot.js
動作環境
以下の Web ブラウザで動作確認済みです。
Mozilla Firefox *
Internet Explorer 6+
Safari *
Opera *
Google Chrome *
また、以下の環境でも動作するよう設計されています。
Greasemonkey (userscript)
Mozilla Firefox Add-On (on XUL)
Node.js
Other non-browser environment
インストール
一般的な方法で動作します。
例:
<script type="text/javascript" src="potlite.min.js"></script> <!--または--> <script type="text/javascript" src="http://api.polygonpla.net/js/pot/potlite/1.23/potlite.min.js"></script>
Node.js の場合。
// Example to define Pot object on Node.js. var Pot = require('./potlite.min.js'); Pot.debug(Pot.VERSION); Pot.Deferred.begin(function() { Pot.debug('Hello Deferred!'); }).then(function() { // ... }); // ...
Greasemonkey (userscript) の例。
// ==UserScript== // ... // @require https: //github.com/polygonplanet/Pot.js/raw/master/potlite.min.js // ... // ==/UserScript== Pot.Deferred.begin(function() { return Pot.request('http://www.example.com/data.json').then(function(res) { return Pot.parseFromJSON(res.responseText); }); }).then(function(res) { Pot.debug(res); // do something... }); //...
PotLite.js をバージョンを限定して Web から直接読み込みたい場合、 上の GitHub リンクでは常に最新になってしまうため 実装の差異による不具合が発生するかもしれません。 そのため、API サーバを用意しました。
v1.23 : http://api.polygonpla.net/js/pot/potlite/1.23/potlite.min.js
これは、1.23 の部分をリリース済みのバージョンに合わせて変更できます。 レポジトリに (例えば 1.xx と) バージョンをタグ付けした時に、 あわせて API サーバに置くようにしています。 例えば Greasemonkey で 1.23 を使いたい場合、
// ==UserScript== // ... // @require http: //api.polygonpla.net/js/pot/potlite/1.23/potlite.min.js // ... // ==/UserScript==
と記述できます。 Greasemonkey に限らず script タグからでもなんでも自由に使ってください。
jQuery プラグインとしての例:
// jQuery を読み込んだ後に実行。 Pot.deferrizejQueryAjax(); // Ajax 系の関数が Pot.Deferred を返すようになる $.getJSON('/hoge.json').then(function(data) { alert(data.results[0].text); }).rescue(function(err) { alert('Error! ' + err); }).ensure(function() { return someNextProcess(); }); // エフェクトなどを Deferred 化する 'deferred' が追加される $('div#hoge').deferred('hide', 'slow').then(function() { // ( hide() が終了したあとの処理) });
Pot.deferrizejQueryAjax() は現状、 ライブラリ側で実行しません。 なので、プラグインを使用する場合は コードの最初などで実行する必要があります。
リファレンス・マニュアル
より詳しい情報はすべてリファレンスに載っています。 基本的な導入や、各メソッド・関数についても扱っています。
Pot.js + PotLite.js - ドキュメントリファレンス - JavaScript非同期処理ライブラリ
動作テスト
以下のページで動作テストができます。 ページを開くと実装されている主な関数・メソッドを全てテストします。
Pot.js + PotLite.js - Test Run - JavaScript Async Library
自動生成されたドキュメント
JSDoc ドキュメント (PotLite.js)
Closure Compiler によりソースコードから自動生成されたドキュメントです。
殆どの関数ごとにサンプルコードを載せているので、ある程度は参考になると思います。 生成物をすべて確認しているわけではないので、誤認識してる箇所もあるかもしれません。 より詳細な実装などは直接ソースコードを参照ください。
不明な点、要望やバグや感想などありましたら @polygon_planet や 下のレポジトリから、またはメールでなんでもどぞです。
レポジトリ
polygonplanet/Pot.js - GitHub
0 notes
potjs · 13 years ago
Text
jQuery.each と Pot.js イテレータで CPU使用率比較グラフ
Web を閲覧していると、突然 CPU 100% になったり 定期的に負荷がかかったりします。 flash などを除くと、それ以外のほとんどは JavaScript による重いループ処理が原因です。 少しずつ改善されてるような気はしますが おそらくもう何年も前から、この問題がついてまわっていたのではないでしょうか。 そしてこのような負荷は、高スペックなマシンでは気付かないと思います。 開発者やテスターが高スペックな PC で動作確認を行ったことにより、 瞬間的な負荷を見過ごされたまま公開、リリースされてしまうこともあると思います。 それを、低スペックなマシンや iPhone などスマホを使っているユーザーが実行し 負荷に耐え切れずカクカクな描画になってしまったり、 最悪フリーズしてしまう場合もあります。 マシンの性能に限らず、例え高スペックマシンでも いくつものアプリケーションを常時起動していて タスクがいっぱいになっているユーザーもこのような事例に該当します。 何らかのアプリケーションを開発する場合、 処理の高速化は常に求められます。 より高速に動作したほうが軽快なのは確かです。 ですがクライアントアプリケーションを作る場合、 CPU 100% 使う処理を 10 秒も 20 秒も続けられてしまったら それはもう不快でしかありません。 さらにそれが非ブロックでなく実行されてたら マシンはもうフリーズのような動かない状態になりっぱなしです。 単純に高速を目指すのではなく、UI のことを考え制御を返すことが重要です。 UI を無視してひたすら高速に実行して 5 秒かかる処理だったら、 定期的に UI に制御を返し 例え数秒遅くなってもバックグラウンドで行い CPU 負荷を抑えることが ユーザーへのストレス軽減として重要と考えています。 さらに非同期で実行することで並列化も可能になり、 逆に本来より速く実行できる可能性もあります。 PotLite.js は、そのような負荷軽減を可能とする JavaScript ライブラリです。 非同期処理をチェインで扱う Deferred オブジェクトを中心に いろいろなループ処理を非同期で実行できる���テレータを実装しています。 イテレータは PotLite.js バージョン 1.21 現在、
forEach
repeat
forEver
iterate
items
zip
map
filter
reduce
every
some
が実装されています。 非同期での実行、同期での実行、そして Deferred チェイン上での実行が可能です。 そして、速度指定できるのが特徴の一つです。
Deferred.forEach(obj, function(value, key) {...})
上のコードが forEach (jQuery での jQuery.each のようなもの) の非同期での通常実行になり、
Deferred.forEach.slow(obj, function(value, key) {...})
上のように .slow と速度を明示することができます。 すると各ループをゆっくり目で実行します。 他にも .fast などの指定ができます。 関数内で return wait(1); 等と Pot.Deferred オブジェクトを返すことで 各ループ間でより細かな wait などの調整ができます。 逆に、非同期イテレートをより速く実行したい場合は Pot.Defered.forEach.ninja(...) と、 最も速く実行するよう定義されている .ninja を指定すると 通常の for 文を単に関数で包んだのと同じくらいの速度で実行できます。 より詳しくは リファレンス を参照してください。 どれくらい変化があるかベンチマークをとってみました。
イテレータ JSON ファイルサイズ CPU 最大使用率 CPU 平均使用率 実行時間 (ms) for 文 1MB 14.52% 10.61% 1211ms. jQuery.each 1MB 16.28% 13.53% 1362ms. Pot.Deferred.forEach 1MB 11.65% 5.53% 1647ms. for 文 5MB 24.85% 21.71% 4717ms. jQuery.each 5MB 27.78% 24.29% 5570ms. Pot.Deferred.forEach 5MB 13.74% 8.61% 8925ms. for 文 10MB 28.14% 25.92% 10699ms. jQuery.each 10MB 31.09% 30.77% 15844ms. Pot.Deferred.forEach 10MB 18.62% 9.77% 38909ms.
同期と非同期の根本的な違いがありますが この結果は、下記のネストループを Core i3 で 5 回実行した平均結果です。 JSON ファイルは、はてなキーワード一覧 から取得した CSV をキーワードだけの JSON に変換したものです。 10MB はキーワードすべて、5MB は半分で切った JSON ファイル、 1MB はそのまた半分です。 Pot.Deferred.forEach によるイテレータは、処理時間が他と比べ長くなっていますが CPU 最大使用率、CPU 平均使用率 共に安定しているのがわかります。 CPU グラフも比較してみました。 すべてのキーワードを対象に、Pot.Deferred.forEach (上) と、jQuery.each (下) をそれぞれ実行した結果です。
Tumblr media
jQuery.each は、途中で「警告:応答しないスクリプト」のダイアログがでてしまいました。 そのため、本来なら Pot.Deferred.forEach のほうが時間がかかると予想してください。 それでも、Pot.Deferred.forEach では jQuery.each に比べ 瞬間的 (もしくは断続的) な負荷を抑えることができています。 これは、対象のデータがどれほど巨大でも 負荷のかからないイテレートが可能なことを示しています。 なお、上記のベンチマークは ある程度負荷のかかるループ処理 を対象としています。 PotLite.js のイテレータは、各ループがある程度重いと判断すると CPU 負荷を抑えるよう働きます。 つまり、逆に言うと 瞬時に終わるような小中規模のループでは、他のループと変わらない速度で実行されるということです。 以下に、小規模のループ結果を記します。
イテレータCPU 最大使用率CPU 平均使用率実行時間 (ms)for 文4.10%3.87%9ms.jQuery.each5.54%4.72%18ms.Pot.Deferred.forEach4.71%4.15%19ms.
この結果は、1MB の JSON ファイルを対象に ユニーク処理をなくした実行結果です。 上と同じく 5 回実行した結果の平均になります。 PotLite.js は、jQuery.each とほぼ同じ実行速度で、 ちょうど for 文を関数で包んだものを実行したのと同じくらいの速度で実行できています。 このような毎回の処理が小さなループでは、 for 文などが最も適していますが 適度に各関数を使うことでコストも減少させることができます。
以下は、テストの使用したソースコードです。
// jQuery.each function benchmark_jQuery() { $.getJSON('hatena.keywords.json?callback=?', { size : '10mb' }, function(data) { var results = []; var start = +new Date; $.each(data.keywords, function(k, word) { if (!/[^a-zA-Z0-9_.-]/.test(word)) { var uniq = true; for (var i = 0; i < results.length; i++) { if (word === results[i]) { uniq = false; break; } } if (uniq) { results.push(word); } } }); $('#result').text((+new Date) - start); }); }
巨大なファイルの転送と負荷のテストのため、ソースのみ記します。
// Pot.Deferred.forEach function benchmark_potlite() { begin(function() { return jsonp('hatena.keywords.json?callback=?', { queryString : { size : '10mb' } }).then(function(res) { var results = []; var start = now(); return Deferred.forEach(res.keywords, function(word) { if (!/[^a-zA-Z0-9_.-]/.test(word)) { var uniq = true; for (var i = 0; i < results.length; i++) { if (word === results[i]) { uniq = false; break; } } if (uniq) { results.push(word); } } }).then(function() { return now() - start; }); }).then(function(time) { $('#result').text(time); }); }); }
以下は、小規模のループとしてテストしたソースコードです。
// jQuery.each function benchmark_jQuery_lite() { $.getJSON('hatena.keywords.json?callback=?', { size : '1mb' }, function(data) { var results = []; var start = +new Date; $.each(data.keywords, function(k, word) { if (!/[^a-zA-Z0-9_.-]/.test(word)) { results.push(word); } }); $('#result').text((+new Date) - start); }); }
// Pot.Deferred.forEach function benchmark_potlite_lite() { begin(function() { return jsonp('hatena.keywords.json?callback=?', { queryString : { size : '1mb' } }).then(function(res) { var results = []; var start = now(); return Deferred.forEach(res.keywords, function(word) { if (!/[^a-zA-Z0-9_.-]/.test(word)) { results.push(word); } }).then(function() { return now() - start; }); }).then(function(time) { $('#result').text(time); }); }); }
PotLite.js
PotLite.js は、Pot.js の軽量バージョンです。 非同期処理のオブジェクト/関数だけに絞ったライブラリです。 経緯などは Pot.js に関する以前の記事 を参照ください。
概要
PotLite.js は、非ブロックでの非同期処理を直列的に書けるようにし、 UI や CPU への負担を軽減するループ処理を中心に実装された JavaScript ライブラリです。 MochiKit ライクな Deferred オブジェクトにより 様々なイテレート (forEach, filter, map, repeat, some など) を可能とします。 ※ここでいう MochiKit ライクとは、JSDeferred とは違い 1 つのチェインが 1 つのインスタンスということです。 ※Deferred チェイン は JSDeferred や MochiKit.Async.Deferred と同じ感覚で扱えます。
ダウンロード
最新
zip
tar.gz
レポジトリ
$ git clone git://github.com/polygonplanet/Pot.js
GitHub : polygonplanet/Pot.js
動作環境
以下の Web ブラウザで動作確認済みです。
Mozilla Firefox *
Internet Explorer 6+
Safari *
Opera *
Google Chrome *
また、以下の環境でも動作するよう設計されています。
Greasemonkey (userscript)
Mozilla Firefox Add-On (on XUL)
Node.js
Other non-browser environment
インストール
一般的な方法で動作します。 例:
<script src="potlite.min.js" type="text/javascript"></script>
Node.js の場合。
// Example to define Pot object on Node.js. var Pot = require('./potlite.min.js'); Pot.debug(Pot.VERSION); Pot.Deferred.begin(function() { Pot.debug('Hello Deferred!'); }).then(function() { // ... }); // ...
Greasemonkey (userscript) の例。
// ==UserScript== // ... // @require https: //github.com/polygonplanet/Pot.js/raw/master/potlite.min.js // ... // ==/UserScript== Pot.Deferred.begin(function() { return Pot.request('http://www.example.com/data.json').then(function(res) { return Pot.parseFromJSON(res.responseText); }); }).then(function(res) { Pot.debug(res); // do something... }); //...
PotLite.js をバージョンを限定して Web から直接読み込みたい場合、 上の GitHub リンクでは常に最新になってしまうため 実装の差異による不具合が発生するかもしれません。 そのため、API サーバを用意しました。
v1.21 : http://api.polygonpla.net/js/pot/potlite/1.21/potlite.min.js
これは、1.21 の部分をリリース済みのバージョンに合わせて変更できます。 レポジトリに (例えば 1.22 と) バージョンをタグ付けした時に、 あわせて API サーバに置くようにしています。 例えば Greasemonkey で 1.21 を使いたい場合、
// ==UserScript== // ... // @require http: //api.polygonpla.net/js/pot/potlite/1.21/potlite.min.js // ... // ==/UserScript==
と記述できます。 Greasemonkey に限らず script タグからでもなんでも自由に使ってください。 ---- jQuery プラグインとしての例:
// jQuery を読み込んだ後に実行。 Pot.deferrizejQueryAjax(); // Ajax 系の関数が Pot.Deferred を返すようになる $.getJSON('/hoge.json').then(function(data) { alert(data.results[0].text); }).rescue(function(err) { alert('Error! ' + err); }).ensure(function() { return someNextProcess(); }); // エフェクトなどを Deferred 化する 'deferred' が追加される $('div#hoge').deferred('hide', 'slow').then(function() { // ( hide() が終了したあとの処理) });
Pot.deferrizejQueryAjax() は現状、 ライブラリ側で実行しません。 なので、プラグインを使用する場合は コードの最初などで実行する必要があります。
リファレンス・マニュアル
より詳しい情報はすべてリファレンスに載っています。 基本的な導入や、各メソッド・関数についても扱っています。
Pot.js + PotLite.js - ドキュメントリファレンス - JavaScript非同期処理ライブラリ
動作テスト
以下のページで動作テストができます。 ページを開くと実装されている主な関数・メソッドを全てテストします。
Pot.js + PotLite.js - Test Run - JavaScript Async Library
自動生成されたドキュメント
JSDoc ドキュメント (PotLite.js)
Closure Compiler によりソースコードから自動生成されたドキュメントです。 殆どの関数ごとにサンプルコードを載せているので、ある程度は参考になると思います。 生成物をすべて確認しているわけではないので、誤認識してる箇所もあるかもしれません。 より詳細な実装などは直接ソースコードを参照ください。
久しぶりにちょっとがんばって重点をまとめてみました。 これを機に、Pot.js (PotLite.js) で遊んでくれると嬉しいです。 不明な点、要望やバグや感想などありましたら @polygon_planet や 下のレポジトリから、またはメールでなんでもどぞです。
レポジトリ
polygonplanet/Pot.js - GitHub
/*<![CDATA[*/ $(function() { $('#pot-polygonplanet-scrollto-dst').attr({ href: 'javascript:void(0)' }).click(function() { $.scrollTo('#pot-polygonplanet-scrollto-src', 800); return false; }); $('#pot-polygonplanet-scrollto-tiny-dst').attr({ href: 'javascript:void(0)' }).click(function() { $.scrollTo('#pot-polygonplanet-scrollto-tiny-src', 800); return false; }); }); /*]]>*/ body div.pot-overlay-content { line-height: 1.4; } .pot-overlay-content h2 { font-size: 150%; margin-top: 38px; margin-bottom: 30px; } dl dt { font-style: normal; font-weight: bold; } body div.pot-separator-image, body div.pot-separator-image-full { display: block; margin: 10px; padding: 0; text-align: left; } body div.pot-separator-image a, body div.pot-separator-image-full a { margin-left: 1em; margin-right: 1em; } body div.pot-separator-image a img, body div.pot-separator-image-full a img { border: 2px solid #999; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } body div.pot-separator-image a img.notify, body div.pot-separator-image-full a img.notify { border: 0 none; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; } body div.pot-separator-image a img.portrait, body div.pot-separator-image-full a img.portrait { border: 1px solid #666; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25), 2px 2px 4px rgba(0, 0, 0, 0.25) inset; } body div.pot-overlay-content div.pot-separator-image-full { padding-left: 0 !important; padding-right: 0; margin-left: 0 !important; margin-right: 0; } body div.pot-overlay-content div.pot-separator-image-full a { margin-left: 0; margin-right: 0; } body .potjs-matome-item { margin: 1em; margin-left: 0; font-weight: bold; font-size: 120%; } body .potjs-matome-item-sub { margin: 0 1em 3em 0; }
11 notes · View notes
potjs · 13 years ago
Text
JavaScriptでDeferredとイテレータの非同期処理用ライブラリ作ってみた
Pot.js という JavaScript ライブラリを作りました。 1ヶ月半くらい前からこつこつ書いてたんですが 実は先日、HDD トラブルでソースコードまるごと紛失してしまったんです。 作業ディレクトリごとなくなっちゃってもう涙目でした。 システム復元とかキャッシュとかいろいろ探したりがんばって HDD の断片から数週間前のデータの一部がいちおう見つかって そのコードの切れ端みたいのと記憶を頼りに元に戻してるところです。 その作業があまりにめんどくさいので、 とりあえず動くところまで元に戻った 非同期処理のオブジェクトのみライブラリにしようと PotLite.js としてコミットしました。 あまり巨大なライブラリより結局のところよかったのかもしれないです。 それでも、一部の関数など足りてない気がしてならない。 ぜんぜん思い出せないけど。。
PotLite.js
PotLite.js は、 非ブロックでの非同期処理を直列的に書けるようにし、 UI や CPU への負担を軽減するループ処理を中心に実装された JavaScript ライブラリです。 MochiKit ライクな Deferred オブジェクトにより 様々なイテレート (forEach, filter, map, filter, repeat, some など) を可能とします。 ※ここで言う MochiKit ライクとは、1 つのチェインが 1 つのインスタンスということです
Download
最新はレポジトリにあります:
polygonplanet/Pot.js - GitHub
ドキュメント/リファレンス
PotLite.js のドキュメントとリファレンス
特徴
クロスブラウザ + Greasemonkey, Firefox アドオン (XUL), Node.js などで動く
まるで jQuery のように繋げやすい Deferred チェイン
Deferred チェイン上で forEach などのイテレートが可能
チェインのコールバック引数を利用した分割代入 (Destructuring-Assignment) ぽいことが可能
イテレータは各ループ処理の負荷を計算し自動で負荷軽減する
各チェイン間やイテレータで実行速度の指定ができる
重たい処理やループを分散させ軽減することが可能
なんだかあまり思いつかなかった。。 重たい処理の軽減というのは、 前に作った Tombloo の Bookmark パッチ で既に近いことを実装してるんです。 というのも、私はブックマークのタグ名をキーワードとして扱ってるせいか タグ数が 10000 とか超えてどんどん処理が重くなっちゃうんです。 マシンスペックにもよりますが、 そういった大きな配列やオブジェクトをループするたび重くて 落ちないか心配になってるようじゃどうしようもないなと思って 瞬間的な (もしくは数秒~数十秒間続く持続的な) 負荷をどうにか抑えられないかと いろいろやってますが、ほとんどは分散させるように実行することと UI に制御を返すことで、だいぶ安定した動作になったのです。 それを Web ブラウザ上でもできないかと 今回実装したライブラリ Pot.js (PotLite.js) の主な目的がそれです。 あとはやはり、JSDeferred の影響が大きいかもしれないです。 MochiKit や dojo (dojo.Deferred) もそうですが、
「JavaScript の高速化とは、単純に速度だけを目指すのではなく UI スレッドの最短ブロック時間のほうが重要。」
つまり、無理と高速にしたせいでその処理間、 たとえ一瞬でもカクカクとなるようではイカんでしょという感じでしょうか。 PotLite.js の非同期イテレータは、 適度に使い分けることで UI スレッドを独占するような処理の 負荷分散的なツールとして使えると思います。 まだまだ改善の余地はあるのですが、 とりあえず安定して動くかたちになったので ここで記事も書いておこうと思ったしだいです。 (というか最近ぜんぜんブログ書いてなかった…)
サンプルコード
サンプル的なコードを書いてみます。 ぜんっぜんいい感じの例が思いつかなくて苦しんでるのですが、 サンプルコード書く専用のプログラマがいてもいいんじゃないかしら。。 Pot.Deferred を使って非同期処理を直列化する例です。 まず、Deferred を使わないで書いた場合、
var elem = document.getElementById('output'); // 5 秒後に foo を出力 setTimeout(function() { elem.value = 'foo'; // さらに 4 秒後に bar を付け足す setTimeout(function() { elem.value += 'bar'; // そしてさらに 3 秒後に baz を付ける setTimeout(function() { elem.value += 'baz'; }, 3000); }, 4000); }, 5000);
上の例は、ネストがどんどん深くなってしまっています。 これを Deferred (Pot.Deferred) を使って書くと、
var elem = document.getElementById('output'); wait(5).then(function() { elem.value = 'foo'; }).wait(4).then(function() { elem.value += 'bar'; }).wait(3).then(function() { elem.value += 'baz'; });
このように書くことができます。 非同期処理を直列的に書けます。 本当はもっと複雑なことに向いてる気もするのですが、 例が思いつかない。。困りました。
続き!
PotLite.js で実装されてるイテレータについて、 CPU 使用率などを for 文と jQuery.each とで比較した結果 を書きました。
レポジトリ
polygonplanet/Pot.js - GitHub
0 notes