LoginSignup
1
1

More than 5 years have passed since last update.

javascriptで継続をつかってPromiseもどきを作ってみたかった

Posted at

Promise風のものをHaskellで学んだ継続モナドを生かしてつくってみたかった。

経緯

Promiseの実装が気になってpolyfillのコードをよみました。

ざっくり読んだだけですが、
callbackの実行状態をステータス管理して、
処理が終わるまでsetTimeoutとかを使って待つような作りになっていて
以外に美しくない実装なのだなぁと思ってました。

そこで継続の概念をつかって、もっとシンプルにPromise風のものが作れないかやってみました。

目指すのは、callbackのメソッドチェーン化です。

定義

class Cont{
    constructor(fn){
        this.runCont = k => fn(x => k(x));
    }
    then(fn){
        const run = this.runCont;
        this.runCont = k => run(a => {
            fn(a,x => k(x));
        });
        return this;
    }
}

実行

new Cont((resolve) => {
    console.log("constructor:before");
    resolve(7);
    console.log("constructor:after");
}).then((a,resolve) => {
    console.log("then1:before");
    console.log("a = " + a);
    setTimeout(function() {
        console.log("resolve1:before");
        resolve(a+1);
        console.log("resolve1:after");
    }, 300);
    console.log("then1:after");
}).then((a,resolve) => {
    console.log("then2:before");
    console.log("a = " + a);
    setTimeout(function() {
        console.log("resolve2:before");
        resolve(a+1);
        console.log("resolve2:after");
    }, 200);
    console.log("then2:after");
}).then((a,resolve) => {
    console.log("then3:before");
    console.log("a = " + a);
    setTimeout(function() {
        console.log("resolve3:before");
        resolve(a+1);
        console.log("resolve3:after");
    }, 100);
    console.log("then3:after");
}).runCont(a => {
    console.log("runCont:"+a);
});

resolveが次のthenの関数を実行してくれます。

結果

constructor:before
then1:before
a = 7
then1:after
constructor:after
resolve1:before
then2:before
a = 8
then2:after
resolve1:after
resolve2:before
then3:before
a = 9
then3:after
resolve2:after
resolve3:before
runCont:10
resolve3:after

思ったとおりの順番で実行できてます。
うまくcallbackをメソッドチェーンで記述できているような気がします。

感想

やりたいことがシンプルに実装できたと思います。

しかし、エラー処理とか、メモリリークとか、処理速度とか、使いやすさとか、
色々考えていくとこの実装では限界があるでしょうか?

そもそもPromiseがよくわかっていない気もしてきました。

今回の実装をもとに、もうちょっと作り込んで問題点を探っていきたいと思います。
いろいろご指摘いただけるとありがたいです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1