5

頭の中で何かをクリアするために...

ライブラリで非同期関数を使用して記述することに慣れていますが、独自の関数を記述するにはどうすればよいですか?

私の質問を説明するために、「MadMathz」というモジュールを作成しました

以下が非同期関数の使用例であることは承知しています。

//load module
var mM = require('./MadMathz');

//perform a function
mM.async_function_addthree(12, function(result) {
  console.log(result)
});

//do something straight afterwards
console.log('Logging this straight after instead of waiting for computation');

関数の 2 番目の引数がコールバックであることは承知していますが、「async_function_addthree」などの関数はどのように定義されていますか? この例では、async_function_addthree が最初の引数に 3 を追加するとします。

私は自分が思っていたことを書こうとして、とても混乱しました。私は完全に間違った道を進んでいますか?私はnode.jsでそこに到達するのに近づいているように感じますが、これは片付ける必要があります.

可能であれば、私をどこかにリンクするのではなく、説明してください。他の人がこの質問から恩恵を受けると確信しています。

4

4 に答える 4

17

実際、これ以上の説明や要件なしに「非同期」関数を作成するのは少し奇妙に思えます。通常、使用法は長いブロック期間を避けることです。したがって、データベースクエリをトリガーする関数があり、これが完了したときに別の関数を呼び出したい場合、その関数はジョブが完了した後に呼び出され、元の関数は即座に制御フローをノードに返します(ECMAscript) .

したがって、次のような構造がある場合

function someJob( callback ) {
    // heavy work
    callback();
}

現在、このコードは依然として非常に同期的に実行されます。それを非同期状態にするために、ノードのprocess.nextTickメソッドを呼び出すことができます

function someJob( callback ) {
    // heavy work
    process.nextTick( callback );
}

ここで何が起こるかというと、その Node は後でそのイベント ループを実行する際にそのコールバックメソッドを実行します (それもある程度インテリジェントに実行します)。EventhonextTickは よりもはるかに効率的であると主張しておりsetTimeout、(ECMAscript コーダーの観点から) ほとんど同じ取引です。したがって、ブラウザでは次のようになります

function someJob( callback ) {
    // heavy work
    setTimeout( callback, 0 );
}

重い作業の後に非同期状態が発生するため、上記の例のメソッドはまったく意味をなさないと言えば、あなたは正しいでしょう。そうですね。実際、これを本当に効率的にするには、重い部分を小さなピースに分解し、同じアイデアを使用する必要があります。.nextTick()

それが最初の私の混乱の理由でもあり、実際にはすべてのタスクがすでにコールバックの可能性を提供しています。

于 2012-10-11T09:13:45.160 に答える
1

これは node.js モジュール コードではありませんが、理解していただければ幸いです。

関数は、JavaScript のファースト クラス オブジェクトです。そのため、それらを変数に割り当てて、値のように他の関数に渡すことができます。関数への参照を取得したら()、関数参照の後に配置して呼び出すだけです。

例:

function async_function_addthree(a, callback) {
    callback(a + 3);
}

これは最初の引数に追加3され、結果を渡す 2 番目の引数を呼び出します。パラメータには好きな名前を付けることができることに注意してください。重要なのは、2 番目のパラメーターが呼び出すことができる関数を保持することだけです。

ただし、コールバックを受け入れる関数は、自動的に非同期になるわけではありません。この例でも、コードは定義された順序で実行されます。つまり、最初async_function_addthreeに 、次にコールバック、async_function_addthreeそしてconsole.log.

を追加してsetTimeout、遅延したコールバックを呼び出すことができます。

function async_function_addthree(a, callback) {
    setTimeout(function() {
        callback(a + 3);
    }, 1000);
}

これにより、1 秒後にコールバックが呼び出されます。Node.js にはさらに優れた方法が組み込まれています。jAndy の回答を参照してください。

ただし、コードが非同期でない場合でも、関数の動作を簡単に変更し、後で既存のコードを壊すことなく非同期にすることができるため、コールバックを使用することは賢明な設計上の選択です。

于 2012-10-11T09:08:11.353 に答える
0

NodeJS プロセスの非同期性は、データベース クエリやファイル システム操作などの一部の作業を外部プロセス (またはおそらく Node の C レイヤー内の一部の作業) に委譲するときに発生します。

通常、プレーンな JavaScript 関数 (Node.js はシングル スレッド) には非同期性はありません。それが有効なケースは多くありません。ただし、それが非常に重く、本当にやりたい場合は、作業を他のプロセスに委譲するか (child_process.fork を参照)、setTimeout を使用して操作を分割することができます (他のリクエストを処理するためにプロセスに息を吹き込みます)。実際、非同期関数として構成する必要があります。

于 2012-10-12T08:25:26.040 に答える