1

ノード js についてさらに学習するための演習として、aws-sdk を使用して SimpleDB (sdb) 用の基本的な CRUD REST サーバーの作成を開始しました。

ドメインを読み取る関数にたどり着くまで、すべてが順調に進んでいました。aws-sdk には、この目的のためにlistDomainsdomainMetadataの 2 つの関数があります。listDomains は、sdb ドメイン名の配列を返します。domainMetadata は、ドメインに関する追加の統計を返しますが、一度に 1 つのドメインについてのみ返します。結果にドメイン名は含まれません。

私のスクリプトは listDomains を実行しており、JSON 応答で問題なく配列を返しています。ただし、API readDomains 関数をより野心的にして、同じ 1 回の API 呼び出しですべてのドメインのメタデータを返すようにしたいと考えています。結局のところ、少数の domainMetadata 呼び出しを同時に実行することは、ノードの async io が輝くべき場所です。

問題は、可変数の呼び出しを実行する方法、それらすべてに同じコールバックを使用する方法、各 domainMetadata 呼び出しの結果をその domainName に一致させる方法がわからないことです (非同期であり、それらが返されることが保証されていないため)要求された順序)、最終的な応答を送信できるように、すべてのメタデータ要求がいつ終了したかを通知します。コードに入れると、私の問題領域は次のとおりです。

domain.receiveDomainList = function(err, data){
 var domainList = [];

 for(var i=0; i<data.DomainNames.length; i++){
   sdb.domainMetaData({"DomainName":data.DomainNames[i]},domain.receiveMetadata);
   // alternatively:   domainList.push({"DomainName":data.DomainNames[i]});
 }
 // alternatively:  
 // async.map(domainList, sdb.domainMetadata, domain.receiveMetadata)

 console.log(domainList);
}

domain.receiveMetadata = function (err, data){
  // I figure I can stash the results one at a time in an array in the
  // parent scope but...

  // How can I tell when all of the results have been received?

  // Since the domainname used for the original call is not returned with 
  // the results how do I tell what result matches what request?
}

async の readme を読んだところによると、map 関数は少なくともメタデータ レスポンスと何らかのブラック マジックによるリクエストを一致させる必要がありますが、「メソッド 'makeRequest' がありません」というエラーが発生し、aws 同期ライブラリでノードが爆破されます。

すべてを取得する方法はありますか: リクエストを並行して実行し、リクエストをレスポンスと照合し、いつすべてを受信したかを知る方法はありますか?

4

1 に答える 1

1

.bind()を使用すると、コンテキストまたはthis値を設定したり、バインドされた関数に主要なデフォルト引数を提供したりできます。

.bind()以下のサンプル コードは、応答コールバックに追加のコンテキストを追加 するために使用する方法を示すためのものです。

以下のコードでは、.bindは次の目的で使用されます。

  • コールバックdomainResultsのコンテキストとしてオブジェクトを設定しますreceiveMetaData
  • 現在のドメイン名を引数としてコールバックに渡します

domainResultsオブジェクトは次の目的で使用されます。

  • 最初のリクエストで受け取った名前の数を追跡する
  • completedCount を追跡します (metaData リクエストからのコールバックごとに増分されます)。
  • リスト内のエラー応答と成功応答の両方を追跡する
  • 完全なコールバックを提供する

説明のみを目的とした完全にテストされていないコード:

domain.receiveDomainList = function(err, data) {
    // Assuming err is falsey
    var domainResults = {
        nameCount: data.DomainNames.length,
        completeCount: 0,
        list: {},
        complete: function() {
            console.log(this.list);
        }
    };

    for (var i = 0; i < data.DomainNames.length; i++) {
        sdb.domainMetaData({ "DomainName": data.DomainNames[i] },
                             domain.receiveMetadata.bind(domainResults, data.DomainNames[i]));
    }
}

domain.receiveMetadata = function(domainName, err, data) {
    // Because of .bind, this === domainResults
    this.completeCount++;
    this.list[domainName] = data || {error: err};

    if(this.completeCount === this.nameCount) {
        this.complete();
    }
}
于 2013-09-12T06:06:01.910 に答える