2017-11-08 6 views
0

私は、ノードコールバックにsetImmediateを使用するのが正しいかどうかを明確にしたいと思います。ノードコールバックでsetImmediateが必要なのはいつですか?

私が調査した例/記事では、コールバックが非同期であることを保証するためにsetImmediateを使用することが最善であると主張しています。最も一般的な例は、値が「キャッシュ」に存在する可能性のある場所です。

const getData = function(id,callback) { 

    const cacheValue = cache[id]; 

    if (cacheValue) { 
     // DON'T DO THIS ... 
     return callback(null,cacheValue); 
     // DO THIS ... 
     return setImmediate(callback,null,cacheValue); 
    } 

    return queryDB(id,function(err,result){ 

     if (err){ 
      return callback(err); 
     } 

     return callback(null,result); 
    }); 
}; 

ここでは混乱します。コールバックでのエラーハンドリングのほとんどのノードの例は決してsetImmediateを呼び出すように見えません。

if (err) { 
    return callback(err); 
} 

の代わり::上記の私の例から

if (err) { 
    return setImmediate(callback,err); 
} 

私はsetImmediate、この場合には必要ではなく、実際にパフォーマンスに影響を与えることができ、なぜこれがあると言ういくつかの引数を読みますか?この例は、キャッシュにアクセスする例と同じではありません。

一貫性があり、常にsetImmediateを使用する方が良いですか?そして、その場合には、理由を次の操作を行いません。(ホスト機能が戻った前に)あなたが「同期コールバックを呼び出している場合

const getData = function(id,callback) { 

    const cacheValue = cache[id]; 

    if (cacheValue) { 
     return setImmediate(callback,null,cacheValue); 
    } 

    return queryDB(id,function(err,result){ 

     if (err){ 
      return setImmediate(callback,err); 
     } 

     return setImmediate(callback,null,result); 
    }); 
}; 

答えて

1

クイック答え

を、あなたはsetImmediate()を使用する必要があります。関数が返された後にコールバックを非同期に呼び出す場合は、コールバックを必要とせず、直接コールバックを呼び出すことができます。長い

を使用すると、コールバックを受け入れ、そのコールバックは、少なくとも時々非同期(あなたの関数が戻った後、将来的にいくつかの不確定時間を意味する)と呼ばれるインタフェースを持っている場合、それは良いです

回答しますたとえ結果がすぐに分かっても、常に非同期に呼び出すように練習してください。これは、関数の呼び出し元とコールバックのユーザーに常に一貫した非同期インターフェイスが表示されるようにするためです。

ご存知のように、この典型的な例はキャッシュされた結果です。結果がキャッシュにある場合、結果はすぐにわかります。

コールバックを常に非同期的に呼び出さなければならないJavascript-landの法律はありません。コールバックが時々同期的に呼び出され、時には非同期的に呼び出されることもありますが、コールバックの使用方法によって発生するバグの影響を受けやすくなります。コールバックが常に非同期に呼び出されると、コールバックの使用方法によって誤ってバグが発生する可能性が低くなります。

の場合:

if (err) { 
    return callback(err); 
} 

私の推測では、これが非同期の場所に既にあるということです。たとえば:

function someFunction(someUrl, callback) { 
    request(someURL, function(response, body, err) { 
     // this is already inside an async response 
     if (err) { 
      callback(err); 
     } else { 
      callback(body); 
     } 
    }); 
} 

私はsetImmediate、この場合には必要ではなく、実際にパフォーマンスに影響を与えることができると言ういくつかの引数を読んで、これはなぜですか?この例は、キャッシュにアクセスする例と同じではありません。

この場合、if (err)は既に非同期コールバックの一部になっているため、追加のsetImmediate()は必要ありません。ホスト関数はすでに返されており、setImmediate()なしでここでコールバックを呼び出すことは、すでに非同期タイミングです。さらにsetImmediate()の必要はありません。

setImmediate()が必要な唯一の時間は、関数の同期本体にまだ残っていて、ホスト関数が返る前にコールバックを呼び出すと、非同期の代わりにコールバックを同期させることです。

概要 setImmediateは、ノードのコールバックので

に必要とされる

、要約します。ホスト関数が返される前に同期的に実行されているコードでは、setImmediate(callback)を使用する必要があります。使用しているコードが非同期コールバックでalredyで、ホスト関数がすでに返っている場合はsetImmediate(callback)を使用する必要はありません。

FYIは、約束が既に自動的にあなたのために処理されているため、非同期プログラミングインターフェイスで(プレーンコールバックではなく)専らプロミスを使用する理由の1つです。それらは、約束が同期して解決されたとしても、解決された約束事の.then()ハンドラが常に非同期に呼び出されることを保証します。

+0

詳細な返信をありがとうございます。さて、あなたはこれを解決する約束を言います。ノードは現在async/awaitをサポートしているので、これは私には別のオプションであると仮定していますか? –

+0

@ClickAhead - はい、 'async/await'は、約束を使用する別の方法です。それを使用するかどうかに関係なく、コールバックを渡すのではなく、インタフェースから約束を返すでしょう。 – jfriend00

関連する問題