2010-04-14 13 views
17

में कैसे करते हैं, इसलिए मैं सराहना करता हूं कि जावास्क्रिप्ट सी # या PHP नहीं है, लेकिन मैं जावास्क्रिप्ट में किसी समस्या पर वापस आ रहा हूं - जेएस के साथ ही नहीं, बल्कि इसका उपयोग।आप जावास्क्रिप्ट कोड निष्पादन * क्रमशः *

मैं एक समारोह है:

function updateStatuses(){ 

showLoader() //show the 'loader.gif' in the UI 

updateStatus('cron1'); //performs an ajax request to get the status of something 
updateStatus('cron2'); 
updateStatus('cron3'); 
updateStatus('cronEmail'); 
updateStatus('cronHourly'); 
updateStatus('cronDaily'); 

hideLoader(); //hide the 'loader.gif' in the UI 

} 

बात है, जावास्क्रिप्ट के जलने कोड में आगे कूद करने की इच्छा के कारण, लोडर कभी नहीं दिखाई देता है 'hideLoader' समारोह सीधे बाद चलता है क्योंकि।

मैं इसे कैसे ठीक कर सकता हूं? या दूसरे शब्दों में, मैं इसे पृष्ठ पर लिखने के क्रम में जावास्क्रिप्ट फ़ंक्शन निष्पादित कैसे कर सकता हूं ...

+0

वादा सभी async अनुरोधों को संभालने के लिए सबसे अच्छा ऑब्जेक्ट है। [वादा ऑब्जेक्ट के साथ async अनुरोधों को ठीक करें] (https://stackoverflow.com/a/47719849/7487135) –

उत्तर

14

समस्या तब होती है क्योंकि AJAX अपनी प्रकृति एसिंक्रोनस में है। इसका अर्थ यह है कि updateStatus() कॉल वास्तव में क्रम में निष्पादित किए जाते हैं लेकिन AJAX अनुरोधों से किसी भी डेटा को पुनर्प्राप्त करने से पहले तत्काल लौटाते हैं और जेएस दुभाषिया hideLoader() तक पहुंचता है।

आपको एजेक्स कॉल समाप्त होने पर एक ईवेंट पर hideLoader() करना चाहिए।

+0

बिल्कुल, जेएस अगली नौकरियों को शुरू करने से पहले अद्यतन स्टार्टस नौकरियों को समाप्त करने की प्रतीक्षा नहीं करता है। यदि cron1 को cron2 शुरू होने से पहले समाप्त करना है, आदि। आपको पिछले कॉल की सफलता पर चलाने के लिए प्रत्येक अपडेटस्टैटस सेट करने की आवश्यकता होगी। – MindStalker

2

इसका कोड के निष्पादन आदेश से कोई लेना देना नहीं है।

लोडर छवि कभी नहीं दिखाती है कि यह कारण है कि आपका कार्य चल रहा है, जबकि UI अद्यतन नहीं होता है। यदि आप यूआई में बदलाव करते हैं, तो वे तब तक प्रकट नहीं होते जब तक कि आप फ़ंक्शन से बाहर निकलें और ब्राउज़र पर नियंत्रण वापस न करें।

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

function updateStatuses(){ 

    showLoader() //show the 'loader.gif' in the UI 

    // start a timeout that will start the rest of the code after the UI updates 
    window.setTimeout(function(){ 
    updateStatus('cron1'); //performs an ajax request to get the status of something 
    updateStatus('cron2'); 
    updateStatus('cron3'); 
    updateStatus('cronEmail'); 
    updateStatus('cronHourly'); 
    updateStatus('cronDaily'); 

    hideLoader(); //hide the 'loader.gif' in the UI 
    },0); 
} 

एक और पहलू है कि यह भी अपने कोड बना सकते हैं नहीं है निष्पादित करने के लिए दिखाई देते हैं खराब। यदि आपके AJAX अनुरोध अतुल्यकालिक हैं, तो फ़ंक्शन प्रतिक्रियाओं की प्रतीक्षा नहीं करेगा। जब ब्राउज़र प्रतिक्रिया प्राप्त करता है तो प्रतिक्रिया का ख्याल रखने वाला फ़ंक्शन चलाया जाएगा। यदि आप प्रतिक्रिया प्राप्त होने के बाद लोडर छवि को छिपाना चाहते हैं, तो आपको ऐसा करना होगा जब आखिरी प्रतिक्रिया हैंडलर फ़ंक्शन चलता है। चूंकि प्रतिक्रियाओं को आपके अनुरोधों को भेजने के क्रम में पहुंचने की आवश्यकता नहीं होती है, इसलिए आपको यह समझने की आवश्यकता होगी कि अंतिम बार आने पर आपको कितने प्रतिक्रियाएं मिलती हैं।

+0

गुफा और डॉ। सबाइटो के लिए धन्यवाद, मैं समझता हूं कि हुड के नीचे क्या चल रहा है, मैं आपके कुछ सुझाव देने जा रहा हूं और देख सकता हूं कि मैं क्या काम कर सकता हूं! –

1

स्थापित Firebug, तो showLoader, updateStatus और hideLoader से प्रत्येक के लिए इस तरह एक पंक्ति जोड़ें:

Console.log("event logged"); 

आप कंसोल विंडो में दिखाई देगा अपने कार्य करने के लिए कॉल, और वे क्रम में हो जाएगा । सवाल यह है कि आपकी "अपडेटस्टैटस" विधि क्या करती है?

संभवतः यह एक पृष्ठभूमि कार्य शुरू करता है, फिर रिटर्न देता है, ताकि पृष्ठभूमि पृष्ठभूमि खत्म होने से पहले आप छुपा लोडर को कॉल तक पहुंच सकें। आपकी अजाक्स लाइब्रेरी में शायद "ऑनकंपलेट" या "ऑनफिनिश" कॉलबैक है - वहां से निम्न अपडेटस्टैटस को कॉल करें।

+0

अद्यतनस्टैटस विधि एक jquery AJAX कॉल से आग लगती है। 'ऑनसुफ' कॉलबैक में लोडर को छिपाने का कारण यह नहीं है क्योंकि मुझे कई कॉलों को पूरा करने की प्रतीक्षा करनी है। लेकिन नीचे दिए गए 'काउंटर' दृष्टिकोण का उपयोग करके मुझे एक वर्कअराउंड मिला है –

12

यदि आप AJAX प्रोग्रामिंग कर रहे हैं तो आपको प्रक्रियात्मक के बजाय ईवेंट के रूप में जावास्क्रिप्ट के बारे में सोचना होगा। दूसरे को निष्पादित करने से पहले आपको पहला कॉल पूरा होने तक प्रतीक्षा करना होगा। ऐसा करने का तरीका कॉलबैक को दूसरी कॉल को बांधना है जो पहले समाप्त होने पर आग लगती है।आपके AJAX पुस्तकालय की अंदरूनी कामकाज के बारे में अधिक जानने के (उम्मीद है कि आपको एक पुस्तकालय का उपयोग कर रहे हैं) के बिना मैं आपको नहीं बता सकते हैं कि कैसे यह करने के लिए, लेकिन यह शायद कुछ इस तरह दिखेगा:

showLoader(); 

    updateStatus('cron1', function() { 
    updateStatus('cron2', function() { 
     updateStatus('cron3', function() { 
     updateStatus('cronEmail', function() { 
      updateStatus('cronHourly', function() { 
      updateStatus('cronDaily', funciton() { hideLoader(); }) 
      }) 
     }) 
     }) 
    }) 
    }) 
}); 

विचार है , updateStatus अपना सामान्य तर्क लेता है, साथ ही इसे समाप्त होने पर निष्पादित करने के लिए कॉलबैक फ़ंक्शन भी लेता है। onComplete को ऐसे फ़ंक्शन में चलाने के लिए फ़ंक्शन को पास करने के लिए यह एक सामान्य रूप से आम पैटर्न है जो इस तरह के एक हुक प्रदान करता है।

अद्यतन

आप jQuery का उपयोग कर रहे हैं, तो आप ऊपर $.ajax() यहाँ पर पढ़ सकते हैं: http://api.jquery.com/jQuery.ajax/

आपका कोड शायद इस तरह दिखता है:

function updateStatus(arg) { 
    // processing 

    $.ajax({ 
    data : /* something */, 
    url : /* something */ 
    }); 

    // processing 
} 

आप संशोधित कर सकते हैं अपने इस तरह के कुछ के साथ अपने दूसरे पैरामीटर के रूप में कॉलबैक लेने के लिए कार्य:

function updateStatus(arg, onComplete) { 
    $.ajax({ 
    data : /* something */, 
    url : /* something */, 
    complete : onComplete // called when AJAX transaction finishes 
    }); 

}

+0

हाय मेगर, मैं jquery का उपयोग कर रहा हूं - यह लागू करने का सबसे अच्छा तरीका क्या होगा? –

5

हम अपने परियोजनाओं में से एक में कुछ इसी तरह है, और हम एक काउंटर का उपयोग करके इसे हल किया। यदि आप प्रत्येक कॉल के लिए updateStatus पर काउंटर बढ़ाते हैं और AJAX अनुरोध के प्रतिक्रिया फ़ंक्शन में इसे कम करते हैं (आप उपयोग कर रहे AJAX जावास्क्रिप्ट लाइब्रेरी पर निर्भर करता है।)

एक बार काउंटर शून्य तक पहुंचने के बाद, सभी AJAX अनुरोध पूर्ण हो जाते हैं और आप कर सकते हैं कॉल करें hideLoader()

var loadCounter = 0; 

function updateStatuses(){ 
    updateStatus('cron1'); //performs an ajax request to get the status of something 
    updateStatus('cron2'); 
    updateStatus('cron3');  
    updateStatus('cronEmail'); 
    updateStatus('cronHourly'); 
    updateStatus('cronDaily'); 
} 

function updateStatus(what) { 
    loadCounter++; 

    //perform your AJAX call and set the response method to updateStatusCompleted() 
} 

function updateStatusCompleted() { 
    loadCounter--; 
    if (loadCounter <= 0) 
     hideLoader(); //hide the 'loader.gif' in the UI 
} 
+0

हाय प्रूटवंडर, मैंने अभी कोशिश की और यह काम करता है! मुझे समाधान –

+3

एड पसंद है, यदि आप इनमें से किसी एक समाधान को पसंद करते हैं, तो क्या आप उस व्यक्ति के उत्तर के बगल में स्थित चेकबॉक्स पर क्लिक करके सबसे अच्छे समाधान की अपनी पसंद को चिह्नित कर सकते हैं? –

+0

+1 कॉलबैक – meagar

0

कदम updateStatus एक और समारोह के लिए कॉल:

यहां एक नमूना है। एक लक्ष्य के रूप में नए कार्य के साथ एक कॉल सेटटाइमआउट करें।

यदि आपके AJAX अनुरोध असीमित हैं, तो आपके पास ट्रैक करने के लिए कुछ होना चाहिए। प्रत्येक कॉलबैक विधि कहीं भी "पूर्ण" ध्वज सेट कर सकती है, और यह देखने के लिए जांचें कि ऐसा करने वाला अंतिम व्यक्ति है या नहीं। यदि यह है, तो इसे hideLoader कॉल करें।

1

जैसा कि अन्य ने बताया है, आप एक तुल्यकालिक ऑपरेशन नहीं करना चाहते हैं। Async गले लगाओ, यही AJAX में ए के लिए खड़ा है।

मैं सिंक v/s async पर एक उत्कृष्ट समानता का उल्लेख करना चाहूंगा। आप entire post on the GWT forum पढ़ सकते हैं, मैं केवल प्रासंगिक अनुरूपताएं शामिल कर रहा हूं।

यदि आप कल्पना कीजिए ...

आप टीवी देख सोफे पर बैठे हैं, और जानते हुए भी कि आप बियर से बाहर हैं, तो आप रन शराब की दुकान करने के लिए नीचे खुश करने के लिए अपने पति या पत्नी से पूछना और आपको कुछ लाता है। जैसे ही आप देखते हैं, आपका पति/पत्नी आगे बढ़ता है, आप सोफे में सोफे और ट्रंडल से बाहर निकलते हैं और फ्रिज खोलते हैं। आपके आश्चर्य के लिए, बियर नहीं है!

बेशक कोई बियर नहीं है, आपका पति/पत्नी शराब की दुकान की यात्रा पर है।आपको तक प्रतीक्षा करना होगा, इससे पहले कि आप की अपेक्षा कर सकते हैं कि वह एक बियर है।

लेकिन, आप कहते हैं कि आप इसे तुल्यकालिक चाहते हैं? फिर से कल्पना कीजिए ...

... पति दरवाजा बाहर चलता है ... अब, आप के चारों ओर पूरी दुनिया बंद हो जाता है, तो आप सांस को नहीं मिलता है, दरवाजा का जवाब, या पास देखने के अपने दिखाएं जबकि वह शहर भर में पर अपनी बीयर लाता है। तुम बस वहाँ बैठते हैं एक मांसपेशी नहीं चलती, और नीले मोड़ जब तक आप चेतना खो ... कुछ अनिश्चितकालीन समय बाद EMTs और एक पति या पत्नी से घिरा ओह, हे कहा, मैं अपने बियर मिल गया जागने के लिए मिलता है।

यह ठीक है जब आप एक सिंक्रोनस सर्वर कॉल करने का आग्रह करते हैं।

10

मैं तुम सब करने की जरूरत है सोचता है कि अपने कोड में यह है:

async: false, 

तो अपने अजाक्स कॉल इस प्रकार दिखाई देगा:

jQuery.ajax({ 
      type: "GET", 
      url: "something.html for example", 
      dataType: "html", 
      async: false, 
      context: document.body, 
      success: function(response){ 

       //do stuff here 

      }, 
      error: function() { 
       alert("Sorry, The requested property could not be found."); 
      } 
     }); 
जाहिर

XML के लिए बदलने के लिए इस जरूरत से कुछ , JSON आदि लेकिन async: false, यहां मुख्य बिंदु है जो जेएस इंजन को तब तक प्रतीक्षा करने के लिए कहता है जब तक सफलता कॉल वापस नहीं आती है (या निर्भर करता है) और फिर आगे बढ़ता है। याद रखें कि इसके लिए कोई नकारात्मक पक्ष है, और यह कि पूरे पृष्ठ को अजाक्स रिटर्न मिलने तक अनुत्तरदायी हो जाता है !!! आमतौर पर मिलीसेकंड के भीतर जो एक बड़ा सौदा नहीं है लेकिन अधिक समय ले सकता है।

आशा इस सही जवाब है और यह आपकी मदद करता है :)

+0

यह एक चाल है। सरल और संक्षिप्त समाधान। बहुत बहुत धन्यवाद। – darksoulsong

+0

हालांकि यह काम करता है यह एक शानदार जवाब नहीं है। आप जेएस को असीमित होना चाहते हैं। ऐसे कई फायदे और परिदृश्य हैं जहां आप इसे अपनी खुद की चीज करने के लिए चाहते हैं और इसे अपने पूरे ऐप के लिए बंद कर देना बिल्कुल असामान्य है। मैं इसके बजाय एक वादा पुस्तकालय का उपयोग करने की सिफारिश करता हूं। यहां एक महान ट्यूटोरियल है। http://dailyjs.com/2014/02/20/promises-in-detail/ – Codex

0

सभी async अनुरोधों को संभालने के लिए सबसे अच्छा समाधान में से एक 'वादा' है।
वादा वस्तु एक एसिंक्रोनस ऑपरेशन की अंतिम समाप्ति (या विफलता) का प्रतिनिधित्व करती है।

उदाहरण:

let myFirstPromise = new Promise((resolve, reject) => { 
    // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed. 
    // In this example, we use setTimeout(...) to simulate async code. 
    // In reality, you will probably be using something like XHR or an HTML5 API. 
    setTimeout(function(){ 
    resolve("Success!"); // Yay! Everything went well! 
    }, 250); 
}); 

myFirstPromise.then((successMessage) => { 
    // successMessage is whatever we passed in the resolve(...) function above. 
    // It doesn't have to be a string, but if it is only a succeed message, it probably will be. 
    console.log("Yay! " + successMessage); 
}); 

Promise

आप 3 async कार्य होते हैं और क्रम में चलाने के लिए उम्मीद, करते हैं इस प्रकार है:

let FirstPromise = new Promise((resolve, reject) => { 
    FirstPromise.resolve("First!"); 
}); 
let SecondPromise = new Promise((resolve, reject) => { 

}); 
let ThirdPromise = new Promise((resolve, reject) => { 

}); 
FirstPromise.then((successMessage) => { 
    jQuery.ajax({ 
    type: "type", 
    url: "url", 
    success: function(response){ 
     console.log("First! "); 
     SecondPromise.resolve("Second!"); 
    }, 
    error: function() { 
     //handle your error 
    } 
    });   
}); 
SecondPromise.then((successMessage) => { 
    jQuery.ajax({ 
    type: "type", 
    url: "url", 
    success: function(response){ 
     console.log("Second! "); 
     ThirdPromise.resolve("Third!"); 
    }, 
    error: function() { 
     //handle your error 
    } 
    });  
}); 
ThirdPromise.then((successMessage) => { 
    jQuery.ajax({ 
    type: "type", 
    url: "url", 
    success: function(response){ 
     console.log("Third! "); 
    }, 
    error: function() { 
     //handle your error 
    } 
    }); 
}); 
इस दृष्टिकोण के साथ

, आप चाहें तो सभी एसिंक ऑपरेशन को संभाल सकते हैं।

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