2013-01-18 14 views
8

इस पर एक नज़र डालने के लिए अग्रिम धन्यवाद।क्लोजर के साथ लूप में नोड ग्रंट असीमित कार्य कार्य नहीं कर रहा

मुझे एक लूप के भीतर एक एसिंक कार्य मिला है जो काम नहीं कर रहा है। लपेटें को बंद करने में मेरी पाशन चर "कुंजी" क्लासिक "अंतिम मान केवल" समस्या है, जहां पाश async कार्य से पहले लंबे समय तक खत्म एक मान देता है से बचने के लिए

  1. , और केवल: मैं करने के लिए सुनिश्चित कर दिया है अंतिम मूल्य प्रदर्शित होता है।
  2. कॉल किया (त्रुटि) (प्रति Gruntjs पूछे जाने वाले प्रश्न) मेरी async कार्य को पूरा करने
  3. उपयोग hasOwnProperty() सुनिश्चित करें कि कुंजी एक वस्तु का एक वास्तविक संपत्ति है, और प्रोटोटाइप से नहीं आती है बनाने के लिए।
  4. किसी चर को निष्पादित करने के मान को असाइन करने के अपवाद के साथ, node.exec उदाहरण के प्रारूप का पालन करें - जो मैंने कोशिश की है, लेकिन इससे मदद नहीं मिली। नीचे पहला संदर्भ देखें।

यह फ़ंक्शन आउटपुट ... कुछ नहीं !? किसी कारण से grunt.log.writeln कथन भी फायरिंग नहीं कर रहे हैं। कार्य त्रुटियों के बिना पूरा करता है। मैंने 20-सेकंड की देरी जोड़ने का भी प्रयास किया, यदि एसिंक कार्य वापस करने से पहले स्क्रिप्ट समाप्त हो रही थी। विचित्र रूप से, अगर मैं "पूर्ण (त्रुटि)" नहीं कहता हूं, तो फाइलें फ़ाइल में लिखी जाती हैं (जब मैं grel.file.write कथन के साथ लेखों को प्रतिस्थापित करता हूं)।

var done = this.async(), 
    exec = require('child_process').exec, 
    myJSON = { 
     "file1" : "C:/home/me/jquery.js", 
     "file2 " : "C:/home/me/grunt.js", 
     ... 
     "fileN" : "C:/home/me/N.js" 
    }, 
    count; 

for (var key in myJSON) { 
    if (myJSON.hasOwnProperty(key)) { 
     (function (key) { 
     exec('type "' + myJSON[key] + '"', 
      function(error, stdout, stderr) { 
      if (error) { 
       grunt.log.writeln('!!! exec error: ' + error); 
      } 
      grunt.log.writeln('stdout: ' + stdout); 
      grunt.log.writeln('stderr: ' + stderr); 
      done(error); 
      } 
     ); 
     })(key); 
    count++; 
    } 
} 

संदर्भ:

http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback https://github.com/gruntjs/grunt/wiki/Frequently-Asked-Questions

उत्तर

12

done() केवल जब पूरे ऑपरेशन पूरा, जब सभी exec() तरीकों उनके कॉलबैक समाप्त हो गया है जिसका मतलब है कि है बुलाया जाना चाहिए। वर्तमान में आप प्रत्येक पुनरावृत्ति पर done कॉलबैक निष्पादित कर रहे हैं। आप आसानी से नोड मॉड्यूल async जो घुरघुराना (grunt.util.async (या forEachSeries के साथ आता है अगर आप exec() तरीकों के क्रम में मार डाला चाहते में forEach विधि का उपयोग कर इस लक्ष्य को हासिल कर सकते हैं

कुछ इस (परीक्षण नहीं) की तरह:।

var done = this.async(); 
var exec = require('child_process').exec; 
var async = grunt.util.async; // updated 
var myJSON = { 
    "file1": "C:/home/me/jquery.js", 
    "file2": "C:/home/me/grunt.js", 
    ... 
    "fileN": "C:/home/me/N.js" 
}; 

async.forEach(Object.keys(myJSON), function(el, cb) { 
    exec('type "' + myJSON[el] + '"', function(error, stdout, stderr) { 
     if (error) { 
      grunt.warn('!!! exec error: ' + error) 
      return cb(error); 
     } 
     grunt.log.writeln('stdout: ' + stdout); 
     grunt.log.writeln('stderr: ' + stderr); 
     cb(); 
    } 
); 
}, function(error) { 
    done(!error); 
}); 
+0

tyvm। एफएक्यू ने मुझे विश्वास दिलाया कि() को एक कार्य के भीतर _each_ asych ऑपरेशन के लिए बुलाया जाना था। यह एक बड़ी मदद थी; मैं आपके समय की सराहना करता हूं। :) – user1354017

+0

तो, यहां ले जाना कि grunt.utils.async उपयोगिताओं को एसिंक कार्यों के साथ काम करने के लिए प्राथमिकता दी जाती है - मैन्युअल रूप से क्लोजर बनाने आदि के विपरीत, सही? – user1354017

+0

यह कोर है रेक्ट, लेकिन सिर्फ परेशान करने के लिए नहीं। सामान्य रूप से Node.js में काम करते समय यह अमूल्य है। https://github.com/caolan/async –

संबंधित मुद्दे