6

私はJavaScriptを学び始めたばかりで、関数への同期呼び出しと非同期呼び出しの組み合わせについて質問があります。これは単なる理論上の問題になりますが、アイデアが伝わることを願っています。

購入する必要があるバナナとオレンジの数を決定する JavaScript プログラムがあるとします。

console.log('buy %d bananas and %d oranges', bananas, oranges)

これで、バナナを何本買えるか決められるようになりましたが、妻にオレンジが何個欲しいか尋ねなければならないので、彼女にテキスト メッセージを送信します。(これを表す非同期関数を書くことができます)。

これは私の当面のアプローチです:

var bananas = 10;
var oranges = 0;
textWife('askAboutOranges',function(number){ oranges = number; }
console.log('buy %d bananas and %d oranges', bananas, oranges)

しかし、私には意味がありません。妻の返事を待たなければならないので、オレンジの数が間に合わないかもしれません。

したがって、プログラムを次のように変更できます。

var bananas = 10;
var oranges = 0;
textWife('askAboutOranges',function(number){ 
   oranges = number;
   console.log('buy %d bananas and %d oranges', bananas, oranges); 
}

しかし、妻からの応答の中に、バナナを含めて何を購入するかを決定するロジックがあるため、これは好きではありません。オレンジはいらないと決めたら、次のようにしなければなりませんか?

var bananas = 10;
var oranges = 0;
if (wantOranges)
{
  textWife('askAboutOranges',function(number){ 
   oranges = number;
   console.log('buy %d bananas and %d oranges', bananas, oranges); 
  }
}
else 
  console.log('buy %d bananas and %d oranges', bananas, oranges); 

だから私の質問は、誰かが私にこのようなことをするための最良/正しい方法を説明できますか?

4

5 に答える 5

7

jQuery Deferredは、ぜひ身につけておきたい優れたツールです。懸念を分離するために、次のようなことをするかもしれません。

function decideHowManyBananas() {
    return 10;
}

function decideHowManyOranges() {
    var deferred = $.Deferred();

    if (wantOranges) {
        textWife('askAboutOranges', function(number) { 
            deferred.resolve(number);
        });
    } else {
        deferred.resolve(0);
    }

    return deferred.promise();
}

$.when(decideHowManyBananas(), decideHowManyOranges()).done(function(bananas, oranges) {
    console.log('buy %d bananas and %d oranges', bananas, oranges);
});
于 2013-07-09T23:00:41.033 に答える
3

正しい/最善の方法はありません - それは常に依存します. 最新の Javascript ライブラリは、Deferreds や Promises などの概念を使用して、複数の非同期呼び出し、同期呼び出し、即時データを同期します。jquery を使用すると、コードは次のように記述できます。

$.when({bananas:10, oranges:1}, textWife('askAboutOranges')).done(function(myList, herList) {
    buyBananas(myList.bananas);
    buyOranges(myList.oranges + herList.oranges);
});

詳細については、 http://api.jquery.com/category/deferred-object/を参照してください。

そして、コード内で洗練された方法で Deferred オブジェクトを作成する方法は次のとおりです。

function decideHowManyOranges() {
    if (!wantOranges)
        return 0;
    return $.Deferred(function(d) {
        textWife('askAboutOranges', function(number) {
            d.resolve(number);
        })
    })
}

numOfBananas = 10

$.when(numOfBananas, decideHowManyOranges()).done(function(bananas, oranges) {
    console.log('buy %d bananas and %d oranges', bananas, oranges);
});
于 2013-07-09T22:46:09.223 に答える
0

関数を準備し、両方のケースで使用してコードの重複を取り除きます。

var bananas = 10;
var oranges = 0;
function buyStuff() {
  console.log('buy %d bananas and %d oranges', bananas, oranges); 
}
if (wantOranges)
  textWife('askAboutOranges',function(number){ 
    oranges = number;
    buyStuff();
  })
else 
  buyStuff();
于 2013-07-09T22:22:44.813 に答える
0

最初の例では、「バナナとオレンジを何個買えばいいですか?」という質問に対する答えを述べています。は、あなたが持っている情報 (必要なバナナの数) と、あなたが持っていない情報 (必要なオレンジの数) の両方に依存するため、最初に不足している情報を取得しないと答えられません。

次に、コードをリファクタリングして、不足している情報が得られるまで質問への回答を延期します。これは、この種の依存関係を解決するための典型的なアプローチです。

次に、オレンジをまったく購入したくない可能性があるため、これでは満足できないと述べます。これは新しい要件であるため、元の質問が無効になり、「バナナを何本購入する必要がありますか?」に変更されます。

欠落している情報の要件を削除することで、質問を変更し、問題を 2 つの質問に特殊化する必要があります。

あなたが提供する最後のコード例は、最初にバナナとオレンジの両方を購入する必要があるか、それともオレンジだけを購入する必要があるかを決定することによってこれを行います。これは実際、問題を解決する最も簡単な方法です.

于 2013-07-09T22:34:28.450 に答える