2012-09-17 48 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(); 

這隻返回undefined ...

回答

9

的原因你「不確定」是因爲你鏈接功能並不返回任何東西:

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

delayOne電話setTimeout,並且沒有返回值(undefined)。

爲了實現自己的目標,你必須使用Q.defer

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

如果你使用很多鏈接的異步調用,那麼你將需要一些庫來逃避'毀滅金字塔':)。我個人更喜歡asyncjs:https://github.com/caolan/async,並且我在一些中型項目上成功使用了它。 – wroniasty

12

由於wroniasty指出,需要從每個這樣的函數返回一個承諾,但你也應該抽象的任何回調導向儘可能使用API​​(如setTimeout),並使用返回promise的API。

setTimeout的情況下,Q已經提供Q.delay(ms)返回,將指定的毫秒數後解決的承諾,完美的替代setTimeout

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(); 

(注:end已替換爲done

相關問題