あなたの例にはいくつかのエラーがあります。
読み取り1
これは「手動で約束をする」ことではなく、通常の非同期呼び出しを行っているだけです。あなたのコードでは、readFile
すぐに呼び出すのでread1
、戻り値は になりreadFile
ますundefined
。に似た動作を得るには、次のようにする必要がread2
ありread3
ます。
var read1 = function(fname, env, success, error){
fs.readFile(fname, enc, function (err, data) {
// Throwing here would just crash your application.
if(err) error(err);
// Returning from inside 'readFile' does nothing, instead you use a callback.
else success(data);
});
};
read2
// Not equivalent to read1 because of the notes above,
// Equivalent to read3, with the fixes I mention below.
var read2 = Q.nfbind(fs.readFile);
read3
var read3 = function (fname, enc) {
var deferred = Q.defer();
fs.readFile(fname, enc, function (error, text) {
if (error) {
// 'error' is already an error object, you don't need 'new Error()'.
deferred.reject(error);
} else {
deferred.resolve(text);
}
// HERE: Again returning a value from 'readFile' does not make sense.
return deferred.promise;
});
// INSTEAD: Return here, so you can access the promise when you call 'read3'.
return deferred.promise.
};
実際nfbind
、コールバックを最後のパラメーターとして取るものなら何でも使用できます。私のコメントで、ファイル名とエンコーディングを受け取り、promise オブジェクトを返す関数を作成するという同じ目標read2
を達成します。read3
それらについては、これを行うことができます:
read2('file.txt', 'utf8').then(function (data) {}, function (err) {}).done();
read3('file.txt', 'utf8').then(function (data) {}, function (err) {}).done();
の場合read1
、次のように呼び出します。
read1('file.txt', 'utf8', function (data) {}, function (err) {});
アップデート
これが回答されて以来、標準の約束は少し進化しましたread3
。
var read4 = function (fname, enc) {
return Q.promise(function(resolve, reject){
fs.readFile(fname, enc, function (error, text) {
if (error) {
// 'error' is already an error object, you don't need 'new Error()'.
reject(error);
} else {
resolve(text);
}
});
});
};
これは、標準の ES6 の約束や bluebird とより一致しているため、コードを進めやすくなります。で説明した方法を使用するread3
と、通常は望ましくないプロミス チェーンで例外をキャプチャする代わりに、例外を同期的にスローする可能性も生じます。遅延アンチパターンを参照してください。