これは本当にばかげた質問だと思いますが、約束を理解するのに苦労しています。
Q (nodejs 用) を使用して、いくつかの非同期関数を同期しています。これは魅力のように機能します。
var first = function () {
var d = Q.defer();
fs.readdir(path,function(err,files){
if(err) console.log(err);
d.resolve(files);
});
return d.promise;
};
var second = function (files) {
var list = new Array;
files.forEach(function(value, index){
var d = Q.defer();
console.log('looking for item in db', value);
db.query(
'SELECT * FROM test WHERE local_name =? ', [value],{
local_name : String,
},
function(rows) {
if (typeof rows !== 'undefined' && rows.length > 0){
console.log('found item!', rows[0].local_name);
d.resolve(rows[0]);
} else {
var itemRequest = value;
getItemData(itemRequest);
}
}
);
list.push(d.promise);
});
return Q.all(list);
};
first()
.then(second)
.done(function(list){
res.send(list);
});
私が抱えている問題は、この小さな機能にあります:
getItemData(itemRequest)
この関数には、いくつかのコールバックが含まれています。promise チェーンは関数を正常に実行しますが、使用するすべてのコールバックを無視します (たとえば、関数で行ういくつかの XHR 呼び出し)。
関数の単純化されたバージョンは次のようになります (アイデアを提供するためだけに):
function getItemData(itemRequest){
helper.xhrCall("call", function(response) {
var requestResponse = JSON.parse(response)
, requestInitialDetails = requestResponse.results[0];
downloadCache(requestInitialDetails,function(image) {
image = localImageDir+requestInitialDetails.image;
helper.xhrCall("call2", function(response) {
writeData(item,image,type, function(){
loadData(item);
});
});
} else {
writeData(item,image,type, function(){
loadData(item);
});
}
});
});
私が使用する xhr 関数は次のようになります。
xhrCall: function (url,callback) {
var request = require("request")
, colors = require('colors');
request({
url: url,
headers: {"Accept": "application/json"},
method: "GET"
}, function (error, response, body) {
if(!error){
callback(body);
}else{
console.log('Helper: XHR Error',error .red);
}
});
}
だから私の質問:
- 関数を変更せずに、配置されているコールバックと promise チェーンを使用できますか?
- または、XHR の promise を使用するように関数を書き直す必要がありますか?
- もしそうなら、プロミスチェーンをどのように書くのが最善でしょうか? forEach で最初の約束を拒否する必要がありますか?
繰り返しますが、これが本当にばかげた質問である場合は申し訳ありませんが、ここでの正しい行動方針がわかりません。
ありがとう!
[編集] Q.nfcall、わかりません
そこで、ノード コールバックを使用できるようにする Q.nfcall を調べてきました。しかし、これがどのように機能するのか正確にはわかりません。誰かがいくつかの非同期 xhr 呼び出しを持つ関数にどのように使用するかの簡単な例を挙げてもらえますか?
私はこれを試しましたが、ご覧のとおり、私が何をしているのか本当に理解していません:
var second = Q.nfcall(second);
function second (files) {
[編集2]
これは、getitemdata 関数のコールバック チェーンの最後の関数です。この関数は基本的に「second」関数と同じことを行いますが、結果を直接プッシュしてから promise を返します。これは前述のとおりに機能しますが、コールバックがデータを返すのを待たないため、追加のコールバック データはすべてありません。
function loadData(item) {
var d = Q.defer();
db.query(
'SELECT * FROM test WHERE local_name =? ', [item],{
local_name : String,
},
function(rows) {
if (typeof rows !== 'undefined' && rows.length > 0){
list.push(d.promise);
}
}
);
});
return Q.all(list);
};