7

私が今書いたものを見るだけで、1つがはるかに小さいことがわかります。したがって、コードゴルフ Option 2の方が良いでしょうが、どちらがよりクリーンであるかについては、私は好みOption 1ます。私はこれに関するコミュニティの意見を本当に望んでいます。

オプション1

something_async({
    success: function(data) {
        console.log(data);
    },
    error: function(error) {
        console.log(error);
    }
});

オプション2

something_async(function(error,data){
    if(error){
        console.log(error);
    }else{
        console.log(data);
    }
});
4

4 に答える 4

6

それらはまったく同じではありません。オプション 2 は引き続き (データ) をログに記録しますが、オプション 1 は成功した場合にのみデータをログに記録します。(編集:少なくともコードを変更する前はそうでした)

そうは言っても、オプション 1 の方が読みやすいです。プログラミングは、誰が最も多くのことを行うために最も少ない行を書くことができるかを競うものではありません/すべきではありません. 私の謙虚な意見では、目標は常に保守可能で拡張可能な (必要に応じて) コードを作成することです。

于 2012-12-20T04:14:58.797 に答える
2

多くの人は、オプション 1 の方が読みやすく維持しやすいと感じるでしょう。2 つの異なる目的のための 2 つの異なるコールバック関数です。これは、2 つの引数が渡されるすべてのPromise Librariesで一般的に使用されます。もちろん、「複数の引数とオプション オブジェクト」という質問は、それとは無関係です (オブジェクトは では役に立ちますがjQuery.ajax、 では意味がありませんpromise.then)。

ただし、オプション #2 はNode.js 規則( NodeGuideも参照) であり、有名なasync.jsなど、その影響を受ける多くのライブラリで使用されています。ただし、この規則は議論の余地があります。私が見つけた上位の Google 検索結果は、WekeRoad: NodeJS Callback ConventionsStackoverflow: What is theSuggested callback style for Node.js libraries? です。.

エラー引数を持つ単一のコールバック関数の理由は、エラーを処理することを開発者に常に思い出させるためです。これは、サーバーサイド アプリケーションでは特に重要です。クライアント側の ajax 関数の初心者の多くは、たとえばエラー処理を気にせず、成功のコールバックが呼び出されない理由を自問します。一方、then-chaining を使用した promise は、エラー コールバックのオプション性に基づいており、それらを次のレベルに伝播します - もちろん、そこでキャッチする必要があります。

于 2012-12-20T04:43:12.353 に答える
0

正直なところ、Promises/Futures/Deferreds/etc... または (/and) モデレーター (またはオブザーバー/サブパブ、ある特定のオブジェクトがデータのソースになる十分な理由がある場合)。

これは 100% の確率ではありません。コールバックが 1 つだけ必要な場合もあります。ただし、(モデル データ内の、またはユーザー インタラクションを視覚化するために) 変更に対応する必要がある複数のビューがある場合、ハードコードされた結果の束を含む単一のコールバックは適切ではありません。

moderator.listen("my-model:timeline_update", myView.update);
moderator.listen("ui:data_request", myModel.request);
button.onclick = function () { moderator.notify("ui:data_request", button.value); }

1 つの大きなコールバックへの依存度が大幅に低下し、コードを組み合わせて再利用できるようになりました。

モデレーターを隠したい場合は、オブジェクトの一部にすることができます:

var A = function () {
        var sys = null,
            notify = function (msg, data) {
                if (sys && sys.notify) { sys.notify(msg, data); }
            },
            listen = function (msg, callback) {
                if (sys && sys.listen) { sys.listen(msg, callback); }
            },
            attach = function (messenger) { sys = messenger; };

        return {
            attach : attach
            /* ... */
        };
    },
    B = function () { /* ... */ },

    shell = Moderator(),
    a = A(),
    b = B();

    a.attach(shell);
    b.attach(shell);

    a.listen("do something", a.method.bind(a));
    b.notify("do something", b.property);

これが少し見慣れているように見える場合は、たとえば Backbone.js と同様の動作です (ただし、extend()オブジェクトに対する動作であり、他のものはバインドされます。私の例では、何が起こっているかを示すためにラッパーを単純化しています)。

Promise は、使いやすさ、保守性、読みやすいコードのもう 1 つの大きな利点です (人々が "promise" とは何かを知っている限り、基本的には、コールバック サブスクリプションを持つオブジェクトを通過します)。

// using jQuery's "Deferred"

var ImageLoader = function () {
    var cache = {},

        public_function = function (url) {
            if (cache[url]) { return cache[url].promise(); }
            var img = new Image(),
                loading = $.Deferred(),
                promise = loading.promise();

            img.onload  = function () { loading.resolve(img); };
            img.onerror = function () { loading.reject("error"); };
            img.src = url;
            cache[url] = loading;
            return promise;
        };

    return public_function;
};

// returns promises
var loadImage = ImageLoader(),

    myImg = loadImage("//site.com/img.jpg");


myImg.done( lightbox.showImg );
myImg.done( function (img) { console.log(img.width); } );

または var blog_comments = [ /* ... */ ],

    comments = BlogComments();

blog_comments.forEach(function (comment) {
    var el = makeComment(comment.author, comment.text),
        img = loadImage(comment.img);

    img.done(el.showAvatar);
    comments.add(el);
});

約束がどれほど強力であるかを示すために、そこにあるすべてのクラフトがあります。そこの呼び出し
を見てください。.forEachこの場合はもう少し明白に見えるかもしれないので、AJAX の代わりに画像の読み込みを使用しています。

何百ものブログ コメントを読み込むことができます。同じユーザーが複数の投稿を行う場合、画像はキャッシュされます。そうでない場合は、画像が読み込まれるのを待つ必要も、ネストされたコールバックを記述する必要もありません。画像は任意の順序で読み込まれますが、適切な場所に表示されます。

これは、AJAX 呼び出しにも 100% 適用できます。

于 2012-12-20T05:40:20.437 に答える
0

Promises非同期やライブラリのようなbluebirdノード スタイルのコールバックを ((err, value)署名を使用して) 受け入れる方法であることが証明されています。したがって、ノード スタイルのコールバックを利用することは有益と思われます。

ただし、問題の例は、以下の関数を使用していずれかの形式に簡単に変換できます。(未テスト)

function mapToNodeStyleCallback(callback) {
  return {
    success: function(data) {
      return callback(null, data)
    },
    error: function(error) {
      return callback(error)
    }
  }
}

function alterNodeStyleCallback(propertyFuncs) {
  return function () {
    var args = Array.prototype.slice.call(arguments)
    var err = args.shift()
    if (err) return propertyFuncs.err.apply(null, [err])
    return propertyFuncs.success.apply(null, args)
  }
}
于 2016-04-08T01:53:49.857 に答える