2014-04-28 7 views
40

में कॉलबैक फ़ंक्शन से मूल्य लौटाना मुझे नोड.जेएस में कॉलबैक फ़ंक्शन से मूल्य लौटने में छोटी परेशानी का सामना करना पड़ रहा है, मैं अपनी स्थिति को यथासंभव आसान समझाने की कोशिश करूंगा।नोड.जेएस

urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {        
    var statusCode = response.statusCode; 
    finalData = getResponseJson(statusCode, data.toString()); 
}); 

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

function doCall(urlToCall) { 
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {        
    var statusCode = response.statusCode; 
    finalData = getResponseJson(statusCode, data.toString()); 
    return finalData; 
}); 
} 

मेरी Node.js कोड, मैं इस तरह है, जहां urlToCall का मूल्य तय किया जाएगा if-else बयान के एक बहुत कुछ है:

if(//somecondition) { 
    urlToCall = //Url1; 
} else if(//someother condition) { 
    urlToCall = //Url2; 
} else { 
    urlToCall = //Url3; 
} 

बात अंदर बयानों के सभी है urlToCall के मूल्य को छोड़कर urllib.request वही रहेगा। तो निश्चित रूप से मुझे उन सामान्य कोड को एक फ़ंक्शन के अंदर रखना होगा। मैंने कोशिश की लेकिन doCall में हमेशा मुझे undefined वापस कर देगा। मैं इस तरह की कोशिश की:

response = doCall(urlToCall); 
console.log(response) //Prints undefined 

लेकिन अगर मैं doCall() अंदर मूल्य प्रिंट यह पूरी तरह प्रिंट, लेकिन यह हमेशा undefined वापस आ जाएगी। मेरे शोध के अनुसार मुझे पता चला कि हम कॉलबैक कार्यों से मूल्य वापस नहीं कर सकते! (क्या यह सच है)? यदि हां, तो क्या कोई मुझे सलाह दे सकता है कि इस स्थिति को कैसे संभाला जाए, क्योंकि मैं प्रत्येक if-else ब्लॉक में डुप्लिकेट कोड को रोकना चाहता हूं।

+0

"यह सच है?" - हाँ बिलकुल। –

+0

@JanDvorak, तो मेरे पास डुप्लिकेट कोड के अलावा कोई विकल्प नहीं है? ;) –

+1

क्या आपकी कुछ कॉलबैक मदद करेगा? मुझे ऐसा विश्वास है। –

उत्तर

77

इसकी undefined क्योंकि console.log(response)doCall(urlToCall); से पहले चलाया गया है। आपको कॉलबैक फ़ंक्शन में भी पास करना होगा, जो तब चलता है जब आपका अनुरोध किया जाता है।

सबसे पहले, आपका कार्य।

function doCall(urlToCall, callback) { 
    urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {        
     var statusCode = response.statusCode; 
     finalData = getResponseJson(statusCode, data.toString()); 
     return callback(finalData); 
    }); 
} 

अब: यह एक कॉलबैक दर्रा

var urlToCall = "http://myUrlToCall"; 
doCall(urlToCall, function(response){ 
    // Here you have access to your variable 
    console.log(response); 
}) 

@Rodrigo, टिप्पणी में एक good resource तैनात। नोड में कॉलबैक पढ़ें और वे कैसे काम करते हैं। याद रखें, यह असीमित कोड है।

+0

+1 धन्यवाद, आपका उदाहरण अच्छा दिखता है। इसे समझने और कार्यान्वित करने की कोशिश करेंगे। –

+4

यह ठीक काम करता है। लेकिन मेरे पास एक प्रश्न है। डॉकल फ़ंक्शन को उस तरफ कॉल करने में। मैं प्रतिक्रिया चर कैसे वापस कर सकता हूँ? उदाहरण के लिए यदि मैं फ़ंक्शन के बाहर उस चर को प्राप्त करना चाहता हूं? – Romeo

+0

@ रोमियो एक ही सवाल यहाँ !! – himanshupareek66

10

मैं पारंपरिक में एक मूल्य Node.js

में कॉलबैक फ़ंक्शन से एक मूल्य लौटने में छोटे मुसीबत का सामना करना पड़ रहा यह एक "छोटे मुसीबत" नहीं है, यह वास्तव में "वापसी" असंभव है एक एसिंक्रोनस समारोह से भावना।

चूंकि आप "मूल्य वापस नहीं कर सकते" के रूप में आपको उस फ़ंक्शन को कॉल करना होगा जिसे आपके पास मानने के बाद मूल्य की आवश्यकता होगी। @display_name ने पहले से ही आपके प्रश्न का उत्तर दिया है, लेकिन मैं बस यह इंगित करना चाहता था कि डॉक में वापसी पारंपरिक तरीके से मूल्य वापस नहीं कर रही है। आप इस प्रकार doCall लिख सकते हैं:

function doCall(urlToCall, callback) { 
    urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {        
     var statusCode = response.statusCode; 
     finalData = getResponseJson(statusCode, data.toString()); 
     // call the function that needs the value 
     callback(finalData); 
     // we are done 
     return; 
    }); 
} 

लाइन callback(finalData); क्या कार्य है जो मूल्य है कि आप async समारोह से मिल की जरूरत है कहता है।लेकिन ध्यान रखें कि वापसी कथन इंगित करने के लिए समारोह यहाँ समाप्त होती है कि प्रयोग किया जाता है हो सकता है, लेकिन यह मतलब यह नहीं है कि मूल्य फोन करने वाले में लौट आता है (फोन करने वाले पहले से ही पर ले जाया गया।)

2

आप क्या चाहते हैं अपने कोड को बहुत अधिक संशोधित किए बिना काम करना है।

यह देखते हुए कि आप Node.js उपयोग कर रहे हैं, तो आप co उपयोग कर सकते हैं और co-request कॉलबैक चिंताओं के बिना एक ही लक्ष्य को प्राप्त करने: आप इस समाधान जो कॉलबैक से छुटकारा मिलता है और एक ही कोड कार्यप्रवाह रहता है की कोशिश कर सकते हैं।

मूल रूप से, आप कुछ इस तरह कर सकते हैं:

function doCall(urlToCall) { 
    return co(function *(){ 
    var response = yield urllib.request(urlToCall, { wd: 'nodejs' }); // This is co-request.        
    var statusCode = response.statusCode; 
    finalData = getResponseJson(statusCode, data.toString()); 
    return finalData; 
    }); 
} 

फिर,

var response = yield doCall(urlToCall); // "yield" garuantees the callback finished. 
console.log(response) // The response will not be undefined anymore. 

ऐसा करने से, हम जब तक प्रतीक्षा करें कॉलबैक फ़ंक्शन खत्म, तो यह से मूल्य मिलता है। किसी भी तरह, यह आपकी समस्या हल करता है। - Node.js के लिए

+0

लेकिन यह ecma6 soultion –

+0

है और यह मेरे प्रदर्शन को प्रभावित करता है –

+0

ecma6 कोई समस्या है? –

0

उदाहरण कोड async समारोह समारोह सिंक करने के लिए:

var deasync = require('deasync'); 

function syncFunc() 
{ 
    var ret = null; 
    asyncFunc(function(err, result){ 
     ret = {err : err, result : result} 
    }); 

    while((ret == null)) 
    { 
     deasync.runLoopOnce(); 
    } 

    return (ret.err || ret.result); 
}