आइए वादों का उपयोग करने के सामान्य नियम से शुरू करें:
<ब्लॉकक्वॉट>हर फ़ंक्शन जो कुछ एसिंक्रोनस करता है उसे एक वादा वापस करना चाहिए
आपके मामले में ये कौन से कार्य हैं? यह है getPrayerInCat
, forEach
कॉलबैक, और Prayer.find
।
हम्म, Prayer.find
एक वादा वापस नहीं करता है, और यह एक पुस्तकालय कार्य है इसलिए हम इसे संशोधित नहीं कर सकते हैं। नियम 2 चलन में आता है:
ऐसे प्रत्येक फ़ंक्शन के लिए तत्काल रैपर बनाएं जो नहीं करता
हमारे मामले में Q के नोड-इंटरफेसिंग हेल्पर्स के साथ यह आसान है:
var find = Q.nbind(Prayer.find, Prayer);
अब हमारे पास केवल वादे हैं, और अब किसी भी आस्थगित की आवश्यकता नहीं है। तीसरा नियम लागू होता है:
<ब्लॉकक्वॉट>
सब कुछ जो async परिणाम के साथ कुछ करता है एक .then
. में चला जाता है कॉलबैक
... और परिणाम लौटाता है। नरक, वह परिणाम एक वादा भी हो सकता है यदि "कुछ" अतुल्यकालिक था! इसके साथ, हम संपूर्ण कॉलबैक फ़ंक्शन लिख सकते हैं:
function getPrayerCount(data2) {
var id = data2.id;
return find({prayerCat:id})
// ^^^^^^ Rule 1
.then(function(prayer) {
// ^^^^^ Rule 3
if (!prayer)
data2.prayersCount = 0;
else
data2.prayersCount = prayer.length;
return data2;
// ^^^^^^ Rule 3b
});
}
अब, हमारे पास कुछ अधिक जटिल है:एक लूप। बार-बार कॉल करना getPrayerCount()
हमें कई वादे मिलेंगे, जिनके अतुल्यकालिक कार्य समानांतर में चलते हैं और अज्ञात क्रम में हल होते हैं। हम उन सभी की प्रतीक्षा करना चाहते हैं - यानी एक वादा प्राप्त करें जो प्रत्येक कार्य समाप्त होने पर सभी परिणामों के साथ हल हो जाए।
ऐसे जटिल कार्यों के लिए, अपने स्वयं के समाधान के साथ आने का प्रयास न करें:
<ब्लॉकक्वॉट>अपनी लाइब्रेरी के API की जांच करें
और वहां हमें Q.all
मिलता है , जो ठीक यही करता है। लेखन getPrayerInCat
अब हवा चल रही है:
function getPrayerInCat(data) {
var promises = data.map(getPrayerCount); // don't use forEach, we get something back
return Q.all(promises);
// ^^^^^^ Rule 1
}
अगर हमें उस सरणी के साथ कुछ भी करने की ज़रूरत है जो Q.all
. है हल करता है, बस नियम 3 लागू करें।