3

JSONで一連の画像の情報を取得し、それらをダイアログに表示して選択するプラグインを作成しています。残念ながら、私の最初の直感は明らかに競合状態になります。

var ImageDialog = function () {};
ImageDialog.prototype.items = [];

ImageDialog.prototype.fetch_images() {
    var parse_images = function(data) {
        // Magically parse these suckers.
        data = awesome_function(data);
        this.items = data;
    };

    magicalxhrclass.xhr.send({"url": 'someurl', "success": parse_images, "success_scope": this});
}

ImageDialog.prototype.render = function () {
    this.fetch_images();
    // XHR may or may not have finished yet...
    this.display_images();
    this.do_other_stuff();
};

var monkey = new ImageDialog();
monkey.render();

parse_images頭のてっぺんから、コールバックを変更して残りのレンダリング手順を含めることで、これを修正できると思います。しかし、それは完全には正しく見えません。なぜこのfetch_imagesメソッドは画像の表示についてたくさんのことを呼び出すのでしょうか?

だから:私はここで何をすべきですか?

延期が役立つと確信していますが、残念ながら、外部ライブラリなしでこれを作成する必要があります。:(

他のコードの臭いについてのコメントもいいでしょう!

4

3 に答える 3

2

これはどう?

var ImageDialog = function () {
    this.items = []; // just in case you need it before the images are fetched
};

ImageDialog.prototype.fetch_images(callback) {
    var that = this;
    function parse_images (data) {
        // Magically parse these suckers.
        data = awesome_function(data);
        that.items = data;
        callback.apply(that);
    };

    magicalxhrclass.xhr.send({"url": 'someurl', "success": parse_images, "success_scope": this});
}

ImageDialog.prototype.render = function () {
    this.fetch_images(function(){
        this.display_images();
        this.do_other_stuff();
    });
};

var monkey = new ImageDialog();
monkey.render();
于 2013-03-20T01:31:35.170 に答える
2

一般に、使用できる基本的な考え方は、通常のプログラムがreturnステートメントを使用する場合(つまり、「私の関数はこれで完了です!」)、非同期の継続渡しプログラムは、代わりに明示的に取得するballcabk関数を使用するというものです。と呼ばれる

function fetch_images(callback){
   magicalXHR({
       success: function(data){
           parse_images(data);
           callback(whatever);
       }
   }
}

または、parse_images自体が非同期関数の場合:

parse_images(data, callback)

これで、fetch_imagesを呼び出すと、コールバックに入った後にコードが返されるときにfetch_imagesが実行されると想定するのではなく、コードが呼び出されます。

fetch_images(function(
   display_images()
})

コールバックを使用することで、従来のプログラムで実行できることをかなりうまくエミュレートできます(実際、ある形式と別の形式の間のかなり機械的な変換です)。ここで発生する唯一の問題は、エラー処理がトリッキーになり、ループなどの言語機能が非同期コールバックでうまく機能せず、コールバックがコールバック地獄にネストする傾向があることです。コールバックが複雑になり始めた場合は、継続渡しスタイルのJavascritにコンパイルされるJavascript方言の1つを使用して調査します(実行時に追加のライブラリを必要とせずに動作するものもあります)。

于 2013-03-20T03:36:02.043 に答える
0

これが何をすべきかについての考えです。

ImageDialog.prototype.fetch_images() {
    var parse_images = function(data) {
        // Magically parse these suckers.
        data = awesome_function(data);
        this.items = data;
        fetch_images.caller() // Unfortunately, this is nonstandard/not in the spec. :(
    };

    magicalxhrclass.xhr.send({"url": 'someurl', "success": parse_images, "success_scope": this});
}

ImageDialog.prototype.render = function () {
    if (this.items === []) {
        this.fetch_images()
        return;
    } else {
        this.display_images();
        this.do_other_stuff();
    };
};

このようにして、実装の詳細をfetch_imagesに渡さず、キャッシュを取得して起動します。私はまだCPSから逃れるために一生懸命努力していますか、それともこれは賢明ですか?

于 2013-03-20T16:49:21.197 に答える