-2

たとえば、同期関数があるとします。

var sum = function(x,y){
  return x+y
}

この関数を非同期で呼び出したい。そんなことがあるものか?以下の関数は非同期関数と見なされますか? これが非同期関数の場合、最初の関数の前に 2 番目の関数のログを記録する必要がありますか? これは非常に単純な例であり、非同期関数の理想的なケースではないことはわかっています。しかし、私はこの基本的なことを明確にしたかっただけです。

function(a, b, c, d, e, f, function(){
  console.log(result);
})
{
   result = sum(a, b);
   result = sum(result, c);
   result = sum(result, d);
   result = sum(result, e);
   result = sum(result, f);
   return
)};


function(a, b, function(){
  console.log(result);
})
{
   result = sum(a, b);
   return
)};

私を助けてください。これが正しくない場合は、どのように記述すればよいか教えてください。

4

4 に答える 4

3

クエンティンの答えに対するあなたのコメントから

通常の同期関数であるが、全体的なフローはこの関数が完了するのを待たずに次の関数に移動する内部操作を含む関数を作成する方法。

言語である JavaScript には、それを行う機能がありません。そのため、実行中の環境に注目して、その環境にその機能があるかどうかを確認します。

NodeJS はそうします。実際には、いくつかあります: setTimeout(これはブラウザが提供するものに少し似ています)、setImmediate、およびprocess.nextTick. あなたのユースケースでsetImmediateは、おそらく最良の選択ですが、詳細については、この質問とその回答を参照してくださいsetImmediate次のようになります。

setImmediate(functionToCall);

(これはグローバルです。何もする必要はありませんrequire。)

これはまさにタイトルが要求することを行います: 同期関数への非同期呼び出しです。


以下のコメントから:

通常の同期関数を呼び出す非同期関数を作成するだけです。非同期関数を意味する場合、この関数を呼び出すとフローが妨げられず、フローは次の関数に進み、この関数は完了後に何か(ロギングなど)を実行できることを意味します

それはあなたの質問が求めるものとまったく同じではありません。:-)

まず、(JavaScript には) 非同期関数はありません。JavaScript で関数を呼び出すと、その関数は同期的に実行されます。つまり、次の 2 つの選択肢があります。

  1. 呼び出しコードはsetImmediate、ノードに関数を非同期的に呼び出すように指示するために使用できます。または

  2. 関数は、おそらくネストされた関数を使用して、それ自体でそれを行うことができます。

ここに#1があります:

function foo() {
    console.log("A");
    setImmediate(bar);
    console.log("B");
}
function bar() {
    console.log("C");
}
foo();

出力:

あ
B
C

これが#2です:

function foo() {
    console.log("A");
    bar("C");
    console.log("B");
}
function bar(arg) {

    setImmediate(run);

    function run() {
        console.log(arg);
    }
}
foo();

...これも出力します

あ
B
C

への引数として "C" がどのように渡されたかに注意してくださいbarbarネストされた関数へのコールバックをスケジュールするだけrunです。run引数を使用します。

于 2013-07-14T14:28:42.160 に答える
0

あなたが何を必要としているのか完全にはわかりませんが、あなたが探しているのは同時関数呼び出しを作成することだと思います。つまり、おそらく計算集約型のコードを実行する必要があり、あなたはそれを望んでいませんこの計算の実行中に他のコードの実行をブロックします。 Node.jsは通常、シングルスレッド プロセスで使用されます。つまり、特定の時間に実行できるコードは 1 つだけですが、実行する方法はいくつかあります。

@TJ Crowder の回答で述べられているように、それを行う 1 つの方法は、関数呼び出しをprocess.nextTickでキューに入れ、イベントループの次のサイクルで実行されるようにすることです。これは、集中的な計算を反復に分割し、各反復が最後のイベント ループ サイクルの後の次のイベント ループ サイクルで実行するためにキューに入れられるのに役立ちます。これは場合によっては役立ちますが、計算を相互に非同期で実行される反復に分割できるとは限りません。Javascript がどのように非同期で実行されるかについて、より詳細な説明を探している場合は、この本を読むことをお勧めします。

Node.jsである種の並行性を実現するには、(私が知っている) 他に少なくとも 2 つの方法があります- ワーカー/スレッドと子プロセスです。要するに、子プロセスは、メイン アプリケーションによって実行されるもう 1 つの Node.js プロセスです。この方法を希望する場合は、 Node.jsのネイティブ *child_process* モジュールを使用して、子プロセスを実行および管理できます。詳細については、公式ドキュメントを参照してください。

3 つ目の方法は、ブラウザーで Web ワーカーを使用する方法と非常によく似た方法でワーカーを使用することです。ワーカーは、メイン アプリケーションとは異なる OS スレッドで実行されるコードのスニペットです。私には、これが並行性を実現する最も簡単な方法のように思えますが、これは最も堅牢な方法ではなく、子プロセスを作成する方が優れていると主張する人もいます。

Workers がMDNでどのように機能するかについての非常に良い説明があります。Node.jsでワーカーを使用するには、 webworker-threadsなどの外部モジュールが必要です。

ドキュメントのスニペットを使用して、サンプルから作成されたコード サンプルを次に示します。

var Worker = require('webworker-threads').Worker;

var worker = new Worker(function(){
    onmessage = function(event) {
        result = sum(event.data.a, event.data.b);
        result = sum(result, event.data.c);
        result = sum(result, event.data.d);
        result = sum(result, event.data.e);
        result = sum(result, event.data.f);
        postMessage(result);
        self.close();
    };
});
worker.onmessage = function(event) {
    console.log("The result is: " + event.data);
};
worker.postMessage({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6});

// Do some other stuff that will happen while your Worker runs...

そうは言っても、ほとんどの人はNode.jsで同時コードを実行することを避けようとします。Javascript の非同期性により、単純で簡潔なバックエンド コードを簡単に記述できます。通常は、絶対に必要でない限り、アプリケーションに同時実行性を導入しようとしないことで、そのように保ちたいと思うでしょう。

于 2013-07-14T15:43:46.387 に答える
0

そんなことがあるものか?

そうではありません。それが行うことはすべて同期操作です。

本質的に非同期のものを扱うときは、非同期コードを使用します。これは、JS ではほぼ完全にイベント処理に限定されます。

以下の関数は非同期関数と見なされますか?

いいえ。コールバックはありますが、実行することはすべて同期的です。

于 2013-07-14T14:13:12.823 に答える
-2

Javascript の場合 (ノードはしばらく脇に置きます) 非同期関数は setTimeout() を介して呼び出す必要があります。SetTimeout は、待機中にスクリプトの実行をブロックしません。

function someThingThatTakesAWhile() { 
    for (var i = 0; i < someVeryLargeNumber; i++) {
        //...
    };
}
setTimeout(function () {
    someThingThatTakesAWhile();
}, 0);

(それをテストしていません。タイプミスを許してください、&c)

しかし、これをノードで実行したい場合、これはあなたが本当に望んでいることではないと思います。

于 2013-07-14T14:25:56.620 に答える