1

Node.JS特にノンブロッキング スタイルの作業を考える場合、コールバックはコーディングの要件としてますます重要になっています。しかし、多くのコルーチン コールバックを記述すると、すぐに読み返すことが難しくなります。

たとえば、次のPyramid Of Doom のようなものを想像してください。

// This asynchronous coding style is really annoying. Anyone invented a better way yet?
// Count, remove, re-count (verify) and log.
col.count(quertFilter,          function(err, countFiltered) {
    col.count(queryCached,      function(err, countCached) {
        col.remove(query,       function(err) {
            col.count(queryAll, function(err, countTotal) {
                util.log(util.format('MongoDB cleanup: %d filtered and %d cached records removed. %d last-minute records left.', countFiltered, countCached, countTotal));
            });
        });
    });
});

は頻繁に目にするものであり、簡単に複雑になる可能性があります。

すべての関数が少なくとも数行長くなると、関数を分離することが可能になり始めます。

// Imagine something more complex

function mary(data, pictures) {
    // Do something drastic
}

// I want to do mary(), but I need to write how before actually starting.

function nana(callback, cbFinal) {
    // Get stuff from database or something
    callback(nene, cbFinal, data);
}

function nene(callback, cbFinal, data) {
    // Do stuff with data
    callback(nini, cbFinal, data);
}

function nini(callback, data) {
    // Look up pictures of Jeff Atwood
    callback(data, pictures);
}

// I start here, so this story doesn't read like a book even if it's quite straightforward.

nana(nene, mary);

しかし、常に多くの通過変数が発生しています。他の関数が間に書かれていると、これは読みにくくなります。関数自体は、独自のファイルを提供することを正当化するには、それ自体では重要でない可能性があります。

4

3 に答える 3

6

のような非同期フロー制御ライブラリを使用しますasync。複数の非同期呼び出しを必要とするコードを構造化するためのクリーンな方法を提供し、それらの間に存在する依存関係 (存在する場合) を維持します。

あなたの例では、次のようにします。

async.series([
    function(callback) { col.count(queryFilter, callback); },
    function(callback) { col.count(queryCached, callback); },
    function(callback) { col.remove(query, callback); },
    function(callback) { col.count(queryAll, callback); }
], function (err, results) {
    if (!err) {
        util.log(util.format('MongoDB cleanup: %d filtered and %d cached records removed. %d last-minute records left.', 
            results[0], results[1], results[3]));
    }  
});

これにより、各関数が順番に実行されます。最初のコールバックが呼び出されると、2 番目のコールバックが呼び出されます。ただし、探しているフローに一致する任意のフローparallelまたはまたはを使用することもできます。waterfallpromise を使用するよりもはるかにクリーンだと思います。

于 2013-01-10T13:54:40.383 に答える
5

コールバックへの別のアプローチは promise です。

例: jQuery Ajax。これはかなり見覚えがあるかもしれません。

$.ajax({
  url: '/foo',
  success: function() {
      alert('bar');
  }  
});

しかし、$.ajax は promise も返します。

var request = $.ajax({
  url: '/foo'
});

request.done(function() {
    alert('bar');
});

$.ajax.success へのコールバックとコールバックとコールバックへのコールバックを提供する代わりに、返された promise を使用できるため、同期動作をシミュレートできるという利点があります。別の利点は、 / をチェーンできることです。 promise を集約し、必要に応じて 1 つの promise-aggregate のエラー ハンドラーを用意します。

この記事はかなり役立つことがわかりました。コールバック、プロミス、およびその他の手法の長所と短所について説明します。

一般的な実装 (AngularJS iirc などで使用) はQです。

于 2013-01-10T12:30:21.340 に答える
2

組み合わせた回答と記事。この回答を編集し、ライブラリ/例/ドキュメントの URL を簡単な形で追加して、すべての人に利益をもたらしてください。

Promise に関するドキュメント

非同期ライブラリ

于 2013-01-15T13:41:45.990 に答える