[解決済み] Node.jsで複数のコールバックを待機させる慣用的な方法
質問
ある一時ファイルに依存する操作を行う必要があるとします。ここでNodeについて話しているので Nodeについて話しているので、これらの操作は明らかに非同期です。 一時ファイルをいつ削除できるかを知るために、すべての操作が終了するのを待つには、どのような方法があるのでしょうか? 一時ファイルをいつ削除することができるかを知るために、すべての操作が終了するのを待つための慣用的な方法は何ですか?
以下は、私がやりたいことを示すいくつかのコードです。
do_something(tmp_file_name, function(err) {});
do_something_other(tmp_file_name, function(err) {});
fs.unlink(tmp_file_name);
しかし、このように書くと、3番目の呼び出しは、最初の2つの呼び出しがファイルを使う機会を得る前に実行される可能性があります。 がファイルを使用する機会を得る前に実行される可能性があります。最初の 2 つの呼び出しがすでに終了している (コールバックを呼び出した) ことを保証する何らかの方法が必要です。 の呼び出しがすでに終了している (コールバックを呼び出した) ことを保証する方法が必要です。 呼び出しを入れ子にすることなく (そして、実際にはそれらを同期させる)、次に進む前に最初の 2 つの呼び出しがすでに終了した (それらのコールバックを呼び出した) ことを保証する方法が必要です。
私は、コールバックでイベントエミッターを使用し、レシーバーとしてカウンターを登録することを考えました。 をレシーバーとして登録することを考えました。カウンターは終了したイベントを受信し、まだ保留中の操作がいくつあるかをカウントします。 をカウントする。最後の操作が終わると、そのファイルを削除する。 ファイルを削除する。しかし、レースコンディションのリスクがありますし、このようなことは通常行われないと思います。 通常、このようなことは行われません。
Nodeの人たちはこの種の問題をどのように解決しているのでしょうか?
どのように解決するのでしょうか?
更新しました。
今、私は見ていることをお勧めします。
-
Promiseオブジェクトは遅延や非同期の計算のために使われます。 Promiseはまだ完了していないが、将来的に期待されている処理を表します。 将来的に期待される処理を表します。
人気のあるプロミスライブラリは ブルーバード . を見てみることをお勧めします。 なぜ約束なのか .
これを回すにはプロミスを使うべき。
fs.readFile("file.json", function (err, val) { if (err) { console.error("unable to read file"); } else { try { val = JSON.parse(val); console.log(val.success); } catch (e) { console.error("invalid json in file"); } } });
この中に
fs.readFileAsync("file.json").then(JSON.parse).then(function (val) { console.log(val.success); }) .catch(SyntaxError, function (e) { console.error("invalid json in file"); }) .catch(function (e) { console.error("unable to read file"); });
-
ジェネレータです。 例えば co .
nodejsとブラウザのためのジェネレータベースのコントロールフローです。 プロミスを使うことで、ノンブロッキングのコードをうまく書けるようになります。
var co = require('co'); co(function *(){ // yield any promise var result = yield Promise.resolve(true); }).catch(onerror); co(function *(){ // resolve multiple promises in parallel var a = Promise.resolve(1); var b = Promise.resolve(2); var c = Promise.resolve(3); var res = yield [a, b, c]; console.log(res); // => [1, 2, 3] }).catch(onerror); // errors can be try/catched co(function *(){ try { yield Promise.reject(new Error('boom')); } catch (err) { console.error(err.message); // "boom" } }).catch(onerror); function onerror(err) { // log any uncaught errors // co will not throw any errors you do not handle!!! // HANDLE ALL YOUR ERRORS!!! console.error(err.stack); }
もし私が正しく理解しているならば、非常に優れた 非同期 ライブラリを見てみるべきだと思います。特に シリーズ . githubページのスニペットからコピーしたものです。
async.series([
function(callback){
// do some stuff ...
callback(null, 'one');
},
function(callback){
// do some more stuff ...
callback(null, 'two');
},
],
// optional callback
function(err, results){
// results is now equal to ['one', 'two']
});
// an example using an object instead of an array
async.series({
one: function(callback){
setTimeout(function(){
callback(null, 1);
}, 200);
},
two: function(callback){
setTimeout(function(){
callback(null, 2);
}, 100);
},
},
function(err, results) {
// results is now equals to: {one: 1, two: 2}
});
さらに、このライブラリはブラウザでも動作させることができます。
関連
-
[解決済み】Nodejs: Errorを解決する方法。ENOENT: そのようなファイルまたはディレクトリがありません
-
[解決済み】「安全なTLS接続が確立される前にクライアントのネットワークソケットが切断されました」(ノード10
-
[解決済み】Express.js req.bodyが未定義です。
-
[解決済み] Node.jsのNPMモジュール(package.json)のdevDependenciesのインストールを防ぐにはどうすればよいですか?
-
[解決済み] Node.js (JavaScript)で待つには?
-
[解決済み] Node.jsでファイルをコピーする最速の方法
-
[解決済み] Node.js プロジェクトの package.json ファイルを自動的にビルドする方法はありますか?
-
[解決済み] Node.jsプロジェクトのフォルダ構造
-
[解決済み] Node.jsで複数のmodule.exportを宣言する
-
[解決済み】node.jsのユーザー認証ライブラリは?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】mongoError: トポロジーが破壊されました
-
[解決済み】AWS STS AssumeRoleへのアクセスを可能にする方法
-
[解決済み] テスト
-
[解決済み】MongoDBのデータ/DBが見つからない
-
[解決済み] Expectアサーションの型エラー -> expect(...).toExistは関数ではない
-
[解決済み] nodejs - http.requestでresponse.writeを使用する場合、第一引数は文字列またはBufferでなければなりません。
-
[解決済み] http-server コマンドが見つかりません。
-
[解決済み] TypeErrorです。リクエストパスにエスケープされていない文字が含まれています。
-
[解決済み] エラーです。Expressでビューの検索に失敗しました
-
[解決済み] エラー: ノード出力を "|head" にパイプするときに EPIPE を書き込む。