Node.js के लिए एसिंक्रोनस फ़ंक्शन कैसे लिखें


114

मैंने इस पर शोध करने की कोशिश की है कि कैसे अतुल्यकालिक कार्यों को लिखा जाना चाहिए। बहुत सारे प्रलेखन के माध्यम से जुताई के बाद, यह अभी भी मेरे लिए अस्पष्ट है।

मैं नोड के लिए एसिंक्रोनस फ़ंक्शन कैसे लिखूं? मुझे त्रुटि ईवेंट हैंडलिंग को सही तरीके से कैसे लागू करना चाहिए?

मेरा सवाल पूछने का एक और तरीका यह होगा: मुझे निम्नलिखित फ़ंक्शन की व्याख्या कैसे करनी चाहिए?

var async_function = function(val, callback){
    process.nextTick(function(){
        callback(val);
    });
};

इसके अलावा, मुझे SO पर यह प्रश्न मिला ("मैं नोड में गैर-अवरोधक एसिंक्रोनस फ़ंक्शन कैसे बनाऊं।") दिलचस्प है। मुझे ऐसा नहीं लगता कि इसका जवाब अभी तक दिया गया है।


14
इसलिए मैं पूछ रहा हूं। यह मेरे लिए स्पष्ट नहीं है कि ये कार्य कैसे भिन्न हैं।
Kriem

मेरा सुझाव है अपने आप को देखो setTimeoutऔर setIntervalअपने पसंदीदा ब्राउज़र में है और उनके साथ चारों ओर के साथ-साथ खेलते हैं। या अजाक्स कॉलबैक (संभवत: नोड अनुभव के सबसे करीबी चीज), या उन चीजों के लिए श्रोताओं को व्यवस्थित करें, जो आप क्लिक और लोड घटनाओं की तरह परिचित हैं। अतुल्यकालिक मॉडल पहले से ही ब्राउज़र में मौजूद है, और वे नोड में बिल्कुल समान हैं।
डेविन

@ डैविन - मुझे लगता है कि पूरी तरह से अतुल्यकालिक मॉडल को समझने के लिए नहीं है।
क्रिअम

@Kriem, मैंने कल कुछ उत्तर दिया जो मदद कर सकता है: stackoverflow.com/questions/6883648/… यह आपके प्रश्न का उत्तर नहीं है, लेकिन यह विषय पर है। कोशिश करें और प्रश्न पढ़ें और वहां उत्तर दें और कोशिश करें और समझने के लिए कोड के साथ खेलें।
13

2
@ रेयानोस "एसिंक्रोनस फ़ंक्शन" की परिभाषा क्या है?
एंडरसन ग्रीन

जवाबों:


85

आप अतुल्यकालिक कार्यों के साथ अतुल्यकालिक IO भ्रमित करने लगते हैं। नोड.जेएस अतुल्यकालिक गैर-अवरुद्ध IO का उपयोग करता है क्योंकि गैर अवरुद्ध IO बेहतर है। इसे समझने का सबसे अच्छा तरीका है कि आप कुछ वीडियो रैन डाहल द्वारा देखें।

मैं नोड के लिए एसिंक्रोनस फ़ंक्शन कैसे लिखूं?

बस सामान्य कार्य लिखें, फर्क सिर्फ इतना है कि उन्हें तुरंत निष्पादित नहीं किया जाता है बल्कि कॉलबैक के रूप में पास किया जाता है।

मुझे त्रुटि इवेंट हैंडलिंग को सही तरीके से कैसे लागू करना चाहिए

आम तौर पर एपीआई आपको पहले तर्क के रूप में एक त्रुटि के साथ कॉलबैक देता है। उदाहरण के लिए

database.query('something', function(err, result) {
  if (err) handle(err);
  doSomething(result);
});

एक सामान्य पैटर्न है।

एक और आम पैटर्न है on('error')। उदाहरण के लिए

process.on('uncaughtException', function (err) {
  console.log('Caught exception: ' + err);
});

संपादित करें:

var async_function = function(val, callback){
    process.nextTick(function(){
        callback(val);
    });
};

उपरोक्त फ़ंक्शन जब कहा जाता है

async_function(42, function(val) {
  console.log(val)
});
console.log(43);

42कंसोल पर अतुल्यकालिक रूप से प्रिंट करेगा । process.nextTickवर्तमान ईवेंटलूप कॉलस्टैक खाली होने के बाद विशेष रूप से आग में। उस कॉल स्टैक के बाद खाली है async_functionऔरconsole.log(43) चला गया है। इसलिए हम ४३ और उसके बाद ४२ को छापते हैं।

इवेंट लूप पर आपको शायद कुछ पढ़ना चाहिए।


मैंने डाहल को देखा है, लेकिन मुझे इस बात पर कोई संदेह नहीं है कि मुझे डर है। :(
क्रिअम

1
@ क्रिएम ने अपडेटेड उत्तर देखें और इवेंट लूप के बारे में
रेयनोस

1
धन्यवाद किले अंतर्दृष्टि। मुझे अब ज्ञान में जो कमी है, उसके बारे में अधिक जानकारी है। :) आपका अंतिम उदाहरण जिस तरह से मदद करता है।
Kriem

मुझे लगता है कि आप अतुल्यकालिक IO के बारे में बयान कर रहे हैं "बेहतर" बहुत सामान्य है। इस अर्थ में हाँ, लेकिन कुल मिलाकर ऐसा नहीं हो सकता है।
जेक बी

अपने पहले कोड उदाहरण में, आप गलत तर्क की जाँच करते हैं, लेकिन बाद में वापस नहीं आए। एक त्रुटि के मामले में, कोड जारी रहेगा और संभावित रूप से आपके आवेदन में गंभीर समस्याएं पैदा करेगा।
गेब्रियल मैकएडम्स

9

सिर्फ कॉलबैक से गुजरना ही काफी नहीं है। आपको फ़ंक्शन async बनाने के लिए, उदाहरण के लिए बसने वाले का उपयोग करना होगा।

उदाहरण: Async फ़ंक्शन नहीं:

function a() {
  var a = 0;    
  for(i=0; i<10000000; i++) {
    a++;
  };
  b();
};

function b() {
  var a = 0;    
  for(i=0; i<10000000; i++) {
    a++;
  };    
  c();
};

function c() {
  for(i=0; i<10000000; i++) {
  };
  console.log("async finished!");
};

a();
console.log("This should be good");

यदि आप उदाहरण के ऊपर चलेंगे, तो यह अच्छा होना चाहिए, उन कार्यों को पूरा करने के लिए इंतजार करना होगा।

छद्म बहुक्षेत्र (async) कार्य:

function a() {
  setTimeout ( function() {
    var a = 0;  
    for(i=0; i<10000000; i++) {
      a++;
    };
    b();
  }, 0);
};

function b() {
  setTimeout ( function() {
    var a = 0;  
    for(i=0; i<10000000; i++) {
      a++;
    };  
    c();
  }, 0);
};

function c() {
  setTimeout ( function() {
    for(i=0; i<10000000; i++) {
    };
    console.log("async finished!");
  }, 0);
};

a();
console.log("This should be good");

यह एक ट्रूली एसिंक्स होगा। यह अच्छा होना चाहिए async समाप्त होने से पहले लिखा जाएगा।



3

यदि आप जानते हैं कि कोई फ़ंक्शन एक वादा वापस करता है, तो मैं जावास्क्रिप्ट में नई async / प्रतीक्षा सुविधाओं का उपयोग करने का सुझाव देता हूं। यह वाक्यविन्यास को तुल्यकालिक बनाता है लेकिन अतुल्यकालिक रूप से काम करता है। जब आप asyncकिसी फ़ंक्शन में कीवर्ड जोड़ते हैं , तो यह आपको awaitउस दायरे में वादे करने की अनुमति देता है :

async function ace() {
  var r = await new Promise((resolve, reject) => {
    resolve(true)
  });

  console.log(r); // true
}

यदि कोई फ़ंक्शन एक वादा वापस नहीं करता है, तो मैं इसे एक नए वादे में लपेटने की सलाह देता हूं जिसे आप परिभाषित करते हैं, फिर उस डेटा को हल करें जो आप चाहते हैं:

function ajax_call(url, method) {
  return new Promise((resolve, reject) => {
    fetch(url, { method })
    .then(resp => resp.json())
    .then(json => { resolve(json); })
  });
}

async function your_function() {
  var json = await ajax_call('www.api-example.com/some_data', 'GET');
  console.log(json); // { status: 200, data: ... }
}

निचला रेखा: वादों की शक्ति का लाभ उठाएं।


यहाँ याद करने के लिए बात है, वादा के शरीर को अभी भी सिंक्रोनाइज़ किया जाता है।
छाया0359

2

यह कोशिश करो, यह नोड और ब्राउज़र दोनों के लिए काम करता है।

isNode = (typeof exports !== 'undefined') &&
(typeof module !== 'undefined') &&
(typeof module.exports !== 'undefined') &&
(typeof navigator === 'undefined' || typeof navigator.appName === 'undefined') ? true : false,
asyncIt = (isNode ? function (func) {
  process.nextTick(function () {
    func();
  });
} : function (func) {
  setTimeout(func, 5);
});

18
4 डाउनवोट्स और एक भी रचनात्मक टिप्पणी नहीं ..: \
ओम

6
@ ओमेर एसओ पर ऐसा जीवन है।
टुकड़ा डिजिटल

6
@NorbertoBezi शायद कोड आप के लिए स्वयं व्याख्यात्मक है, लेकिन जवाब पोस्ट करने वाले के लिए नहीं। यही कारण है कि हमेशा डाउनवोटिंग पर समझाने के लिए एक अच्छा अभ्यास है।
ओमेर

0

मैं नोड के लिए इस तरह के कार्य के लिए कई घंटे काम कर रहा हूं। मैं मुख्य रूप से सामने वाला लड़का हूं।

मुझे यह काफी महत्वपूर्ण लगता है, क्योंकि सभी नोड तरीके कॉलबैक के साथ असिंक्रोनस डील करते हैं और इसे प्रॉमिस में बदलना बेहतर होता है।

मैं बस एक संभावित परिणाम, अधिक दुबला और पठनीय दिखाना चाहता हूं। ECMA-6 का उपयोग async के साथ आप इसे इस तरह से लिख सकते हैं।

 async function getNameFiles (dirname) {
  return new Promise((resolve, reject) => {
    fs.readdir(dirname, (err, filenames) => {
      err !== (undefined || null) ? reject(err) : resolve(filenames)
    })
  })
}

(undefined || null)के लिए है repl भी अपरिभाषित काम का उपयोग कर, (पढ़ने घटना प्रिंट पाश) परिदृश्यों।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.