2012-09-17 12 views
8

私はいくつかの問題 "Q"(https://github.com/kriskowal/q)javascriptのための約束ライブラリを使用する方法を理解する:qでコールバックチェーンを実行するにはどうすればよいですか?

var delayOne = function() { 
    setTimeout(function() { 
     return 'hi'; 
    }, 100); 
}; 

var delayTwo = function(preValue) { 
    setTimeout(function() { 
     return preValue + ' my name'; 
    }, 200); 
}; 

var delayThree = function(preValue) { 
    setTimeout(function() { 
     return preValue + ' is bodo'; 
    }, 300); 
}; 

var delayFour = function(preValue) { 
    setTimeout(function() { 
     console.log(preValue); 
    }, 400); 

}; 

Q.fcall(delayOne).then(delayTwo).then(delayThree).then(delayFour).end(); 

未定義これだけ戻って...

答えて

9

var delayOne = function() { 
    setTimeout(function() { 
    return 'hi'; 
    }, 100); 
}; 

delayOnesetTimeoutを呼び出し、何も(undefined)を返しません:あなたは、連鎖している機能は何も戻っていないので、あなたが「未定義」を取得理由があります。

var delayOne = function() { 
    var d = Q.defer();  
    setTimeout(function() { 
    d.resolve("HELLO"); 
    }, 100); 
    return d.promise; 
}; 

var delayTwo = function(preValue) { 
    setTimeout(function() { 
    alert(preValue); 
    }, 
    400); 
}; 

delayOne().then (delayTwo); 

http://jsfiddle.net/uzJrs/2/

+0

解決に感謝します。その面では、Qを使うとコード品質が向上すると思いますが、それはハード側の依存関係につながります。この問題があれば経験はありますか? – bodokaiser

+1

多くの連鎖した非同期呼び出しを使用する場合は、「Pyramid of Doom」からエスケープするライブラリが必要です。私は個人的にはasyncjs:https://github.com/caolan/asyncを好んでおり、中規模のプロジェクトでは成功しました。 – wroniasty

12

wroniastyが指摘したように、あなたはこれらの関数のそれぞれからの約束を返す必要があるが、あなたはまた、抽象任意のコールバックが志向すべきである:あなたがQ.deferを使用する必要がありますあなたの目標を達成するために

できるだけ多くのAPI(setTimeoutなど)を使用し、代わりに約束を返すAPIを使用します。 setTimeoutの場合

、Qはすでに setTimeoutを交換するために指定されたミリ秒数後に解決される約束を返し Q.delay(ms)、完璧を提供しています。

var delayOne = function() { 
    return Q.delay(100).then(function() { 
     return 'hi'; 
    }); 
}; 

var delayTwo = function(preValue) { 
    return Q.delay(200).then(function() { 
     return preValue + ' my name'; 
    }); 
}; 

var delayThree = function(preValue) { 
    return Q.delay(300).then(function() { 
     return preValue + ' is bodo'; 
    }); 
}; 

var delayFour = function(preValue) { 
    return Q.delay(400).then(function() { 
     console.log(preValue); 
    }); 
}; 

Q.fcall(delayOne).then(delayTwo).then(delayThree).then(delayFour).done(); 

(注:enddoneに置き換えられました)