javascript मैं एक कॉलबैक कैसे बना सकता हूं जिसके लिए उसके बच्चे के कार्य की जानकारी आवश्यक है




node.js callback (4)

मैं एक परियोजना में काम कर रहा हूं जो हरका (एक एसएमटीपी सर्वर) प्लगइन के लिए नोड.जेएस का उपयोग करता है।

यह नोड है। जेएस और मेरे पास थोड़ी सी समस्या है, जिसका कॉलबैक है। मैं एक विशेष कॉलबैक का उपयोग करने के लिए इस विशेष कोड को रूपांतरित करने में सक्षम नहीं हूं।

तो, यह वह कोड है जो मेरे पास है:

exports.hook_data = function (next, connection) {
    connection.transaction.add_body_filter('', function (content_type, encoding, body_buffer) {
        var header = connection.transaction.header.get("header");
        if (header == null || header == undefined || header == '') return body_buffer;

        var url = 'https://server.com/api?header=' + header ;
        var request = require('request');
        request.get({ uri: url },
          function (err, resp, body) {
              var resultFromServer = JSON.parse(body);
              return ChangeBuffer(content_type, encoding, body_buffer, resultFromServer);
          }
        );
    });
    return next();
}

यह कोड काम नहीं करता क्योंकि यह जारी रखने के लिए अनुरोध के कॉलबैक की प्रतीक्षा नहीं करता है। मुझे next() से पहले अनुरोध पूरा करना होगा;

और ये आवश्यकताएं हैं:

  1. exports.hook_data के अंत में exports.hook_data वापस next() लिए अनिवार्य है next() । लेकिन अनुरोध के बाद ही इसे वापस करना होगा।
  2. मुझे add_body_filter में एक Buffer वापस करने की आवश्यकता है लेकिन मुझे सर्वर से प्राप्त जानकारी के साथ बफर बनाने की आवश्यकता है
  3. अनुरोध प्राप्त करने के लिए मुझे एक पैरामीटर ( header ) का उपयोग करने की आवश्यकता है जो मेरे पास केवल add_body_filter अंदर है

इसलिए मुद्दा यह है कि मैं add_body_filter से पहले अनुरोध नहीं कर सकता और परिणाम को कॉलबैक के अंदर डाल सकता हूं क्योंकि मुझे जो पैरामीटर अनुरोध करना है, वह केवल add_body_filter अंदर ही है

कृपया कोई सलाह?


लेनदेन ऑब्जेक्ट और हैडर ऑब्जेक्ट के लिए हरका मैनुअल को देखते हुए मुझे नहीं लगता कि add_body_filter पर हैडर का कोई निर्भरता है इसके अलावा आपका कोड add_body_filter पर कोई निर्भरता नहीं दिखाता है। तो आपकी तीसरी आवश्यकता अवैध लगती है

यह विचार करते हुए, मुझे लगता है कि निम्नलिखित छद्मकोड (जैसा कि मैं परीक्षण नहीं कर सकता) आपके लिए काम करना चाहिए।

exports.hook_data = function (next, connection) {
    var header = connection.transaction.header.get("header");
    if (header == null || header == undefined || header == '') {
        return next();

    var url = 'https://server.com/api?header=' + header ;
    var request = require('request');
    request.get({ uri: url },
        function (err, resp, body) {
            var resultFromServer = JSON.parse(body);
            connection.transaction.add_body_filter('', function (content_type, encoding, body_buffer) {
                return ChangeBuffer(content_type, encoding, body_buffer, resultFromServer);
            });
            next();
        }
    );
}

अगर Haraka मैनुअल add_body_filter पर हेडर की निर्भरता को उजागर करने में विफल रहा है और / या आप इसे अपने व्यावहारिक अनुभव के आधार पर खोज चुके हैं, तो क्वाई के दृष्टिकोण को जाने का तरीका लगता है

यदि आप सोच रहे हैं कि अगले () वी / एस वापसी का उपयोग कब करना होगा ()


जावास्क्रिप्ट प्रकृति में अतुल्यकालिक है एसिंक्रोनस एक प्रोग्रामिंग पैटर्न है जो गैर-अवरोधक कोड की सुविधा प्रदान करता है अर्थात कोड को किसी विशेष पंक्ति को निष्पादित करने के लिए किसी अन्य फ़ंक्शन / प्रक्रिया पर रोक नहीं है या नहीं। रेफरी: कोडमेंटर अनुच्छेद

विकिपीडिया से

Node.js एक ईवेंट-संचालित आर्किटेक्चर प्रदान करता है और एक गैर-अवरुद्ध I / O API को वास्तविक समय वेब अनुप्रयोगों के लिए एप्लिकेशन के थ्रुपुट और स्केलेबिलिटी को अनुकूलित करने के लिए डिज़ाइन किया गया है

तुम क्या कर सकते हो?

  1. नींद का प्रयोग करें / प्रतीक्षा करें अर्थात setTimeout (अनुशंसित नहीं)
  2. कुछ async लिब जैसे https://github.com/caolan/async का उपयोग करें (अनुशंसित)
  3. क्यू की तरह कुछ वादा lib का उपयोग करें

जब तक आप तुल्यकालिक, अवरुद्ध कार्यों का उपयोग करने के लिए तैयार नहीं हैं, आपके द्वारा गिने गए आवश्यकताओं को पूरा करना असंभव है।

मैं प्रत्येक आवश्यकता के तहत कारणों की जांच करता हूं और देखें कि क्या आप अपने लक्ष्यों को एक अलग तरीके से पूरा करते हैं।

अंकित मूल्य पर, आपके पास केवल उस कोड को देखते हुए, मैं exports.hook_data के अनुबंध को बदलने का एक तरीका exports.hook_data ताकि आप next() request.get को अंदर से कॉल कर सकें। कॉलबैक कॉल करें।


Async.js या वादे का प्रयोग करें

एसिंक कार्यान्वयन:

exports.hook_data = function (next, connection) {
  async.waterfall([
    function( done ) {
      connection.transaction.add_body_filter('', function( content_type, encoding, body_buffer ) {
        var header = connection.transaction.header.get("header");
        if ( header == null || header == undefined || header == '' ) {
          done(null, body_buffer);
        }
        done(null, header);
      });
    },
    function( header, done ) {
      var url = 'https://server.com/api?header=' + header;
      var request = require('request');
      request.get({ uri: url },
        function( err, resp, body ) {
          // do something if there's an error
          var resultFromServer = JSON.parse(body);
          done(null, ChangeBuffer(content_type, encoding, body_buffer, resultFromServer));
        }
      );
    }
  ], function( error, buffer ) {
    // do something if there's error
    next(buffer);
  });
}

यहां बहुत कुछ है और मैं आपको async.js # waterfall पर दस्तावेज़ पढ़ने की सलाह देता हूं। मूल रूप से यह प्रत्येक एसिंक कॉल को फ़ंक्शन ब्लॉक पर टूटता है और अगले ब्लॉक पर जारी होने से पहले इसे वापस करने के लिए इंतजार करता है

दोबारा, क्योंकि ये सभी एसिंक हैं, नोड इन कार्यों को आईओ ईवेंट लूप के पास प्रस्तुत करते हैं और इसके बारे में ध्यान रखा जाता है (गैर-अवरुद्ध)। जब यह थ्रेड प्रतीक्षा कर रहा है, यह संभवतः अगली अनुरोध पर ले जाया जाएगा, जबकि यह अनुरोध प्रतीक्षा कर रहा है।





haraka