आप बाइंडइन्वायरमेंट का थोड़ा गलत उपयोग कर रहे हैं। क्योंकि जहां इसका उपयोग किया जा रहा है वह पहले से ही एक फाइबर में है और नॉक्स क्लाइंट से आने वाला कॉलबैक अब फाइबर में नहीं है।
BindEnvironment के दो उपयोग के मामले हैं (जिनके बारे में मैं सोच सकता हूँ, और भी बहुत कुछ हो सकता है!):
-
आपके पास एक वैश्विक चर है जिसे बदलना है लेकिन आप नहीं चाहते कि यह अन्य उपयोगकर्ता के सत्रों को प्रभावित करे
-
आप किसी तृतीय पक्ष api/npm मॉड्यूल (जो मामला प्रतीत होता है) का उपयोग करके कॉलबैक प्रबंधित कर रहे हैं
Meteor.bindEnvironment
एक नया फाइबर बनाता है और वर्तमान फाइबर के चर और पर्यावरण को नए फाइबर में कॉपी करता है। जब आप अपने नॉम मॉड्यूल की विधि कॉलबैक का उपयोग करते हैं तो आपको इसकी आवश्यकता होती है।
सौभाग्य से एक विकल्प है जो आपके लिए प्रतीक्षा कर रहे कॉलबैक का ख्याल रखता है और कॉलबैक को Meteor.wrapAsync
नामक फाइबर में बांधता है। ।
तो आप यह कर सकते हैं:
आपके स्टार्टअप फ़ंक्शन में पहले से ही एक फाइबर है और कोई कॉलबैक नहीं है, इसलिए आपको यहां बाइंडएनवायरमेंट की आवश्यकता नहीं है।
Meteor.startup(function () {
if (Projects.find().count() === 0) {
insertRecords();
}
});
और आपका इंसर्ट रिकॉर्ड फंक्शन (wrapAsync का उपयोग करके) करता है ताकि आपको कॉलबैक की आवश्यकता न हो
function insertRecords() {
console.log("inserting...");
var client = Knox.createClient({
key: apikey,
secret: secret,
bucket: 'profile-testing'
});
client.listSync = Meteor.wrapAsync(client.list.bind(client));
console.log("created client");
try {
var data = client.listSync({ prefix: 'projects' });
}
catch(e) {
console.log(e);
}
if(!data) return;
for (var i = 1; i < data.Contents.length; i++) {
console.log(data.Contents[i].Key);
if (data.Contents[i].Key.split('/').pop() == "") {
Projects.insert({ name: data.Contents[i].Key, contents: [] });
} else if (data.Contents[i].Key.split('.').pop() == "jpg") {
Projects.update( { name: data.Contents[i].Key.substr(0,
data.Contents[i].Key.lastIndexOf('.')) },
{ $push: {contents: data.Contents[i].Key}} );
} else {
console.log(data.Contents[i].Key.split('.').pop());
}
}
});
ध्यान रखने योग्य कुछ बातें। रेशे धागों की तरह नहीं होते। NodeJS में केवल एक ही थ्रेड होता है।
फ़ाइबर ऐसी घटनाओं की तरह होते हैं जो एक ही समय में चल सकती हैं लेकिन प्रतीक्षा प्रकार की स्थिति होने पर एक-दूसरे को अवरुद्ध किए बिना (जैसे इंटरनेट से फ़ाइल डाउनलोड करना)।
तो आपके पास सिंक्रोनस कोड हो सकता है और अन्य उपयोगकर्ता की घटनाओं को अवरुद्ध नहीं कर सकता है। वे दौड़ने के लिए बारी-बारी से दौड़ते हैं लेकिन फिर भी एक ही धागे में दौड़ते हैं। तो इस प्रकार Meteor का सर्वर साइड पर सिंक्रोनस कोड होता है, जो सामान की प्रतीक्षा कर सकता है, फिर भी अन्य उपयोगकर्ता इससे अवरुद्ध नहीं होंगे और सामान कर सकते हैं क्योंकि उनका कोड एक अलग फाइबर में चलता है।
क्रिस माथेर के पास इस पर http://eventedmind.com
. पर कुछ अच्छे लेख हैंMeteor.wrapAsync क्या करता है?
Meteor.wrapAsync
आप इसे पहले पैरामीटर के रूप में देते हैं और इसे वर्तमान फाइबर में चलाते हैं।
यह इसके लिए एक कॉलबैक भी संलग्न करता है (यह मानता है कि विधि एक अंतिम परम लेती है जिसमें कॉलबैक होता है जहां पहला परम एक त्रुटि है और दूसरा परिणाम जैसे function(err,result)
।
कॉलबैक Meteor.bindEnvironment
. से बंधा हुआ है और कॉलबैक सक्रिय होने तक वर्तमान फाइबर को अवरुद्ध करता है। जैसे ही कॉलबैक सक्रिय होता है यह result
लौटाता है या err
फेंकता है ।
इसलिए एसिंक्रोनस कोड को सिंक्रोनस कोड में कनवर्ट करना बहुत आसान है क्योंकि आप कॉलबैक का उपयोग करने और गहरे कार्यों को नेस्ट करने के बजाय अगली पंक्ति पर विधि के परिणाम का उपयोग कर सकते हैं। यह आपके लिए बाइंडएनवायरमेंट का भी ख्याल रखता है ताकि आपको अपने फाइबर के दायरे को खोने की चिंता न करनी पड़े।
अपडेट करें Meteor._wrapAsync
अब है Meteor.wrapAsync
और प्रलेखित।