2014-04-24 4 views
8

मैं एक jQuery पुस्तकालय का उपयोग कर रहा bootboxजावास्क्रिप्ट/jquery में सी # के बराबर क्या है? जब मैं "ठीक" बटन पर क्लिक करें

bootbox.dialog({ 
    title: "Group", 
    buttons: { 
     success: { 
      label: "OK", 
      className: "btn-success", 
      callback: function() { 
       postForm(); 
      } 
     } 
    } 
}); 

function postForm() {   
    $.ajax({ 
     type: "POST", 
     url: $("#add-group").val(), 
     data: $("#form").serialize(), 
     success: function (data) { 
      return true; 
     }, 
     error: function (XMLHttpRequest, textStatus, errorThrown) { 
      return false; 
     } 
    }); 
} 

कहा जाता है, जब तक कि मैं इस तरह एक झूठी मान:

callback: function() { 
    return false; 
} 

संवाद बंद हो जाएगा।

कॉलबैक फ़ंक्शन में, मैं postForm पर कॉल कर रहा हूं जो एक ऐसा फ़ंक्शन है जो कुछ ऑपरेशन करने के लिए मेरे सर्वर पक्ष में AJAX कॉल करता है। उस ऑपरेशन के नतीजे के आधार पर, मैं संवाद को अभी भी खोलना चाहता हूं।

लेकिन क्योंकि यह एक AJAX कॉल है, और परिणाम वापस आने में कुछ समय लगता है, तो मेरे परिणाम के बावजूद संवाद postForm() के तुरंत बाद बंद हो जाता है।

मैं AJAX कॉल के परिणाम के लिए जावास्क्रिप्ट कैसे कह सकता हूं?

callback: function() { 
    var result = await postForm(); 
    return result; 
} 
+2

जावास्क्रिप्ट थ्रेड नहीं है, इसलिए प्रतीक्षा नहीं संभव है। केवल सिंक्रनाइज़ ऑपरेशंस हैं (जहां कोड को इसके क्रम में समान रूप से निष्पादित किया जाता है) और एसिंक ऑपरेशंस, जहां ऑपरेशन कॉल करने के बाद कॉलबैक फ़ंक्शन कॉल करता है। इसके लिए एक कामकाज jquery वादा() है, जो वास्तव में अप्रत्यक्ष कॉलबैक है। – setec

+0

तो मैं वादा() में postForm() लपेट सकता हूँ? –

+0

मुझे लगता है कि आप 'postForm()' में '$ .when' आज़मा सकते हैं। मुझे यकीन नहीं है, लेकिन इसे –

उत्तर

6

मुझे लगता है कि Promises बिल्कुल वही है जो आप पूछ रहे हैं।

.promise()

वापसी निरीक्षण करने के लिए जब संग्रह करने के लिए बाध्य एक खास प्रकार के सभी कार्यों, पंक्तिबद्ध या नहीं एक वादा वस्तु, समाप्त कर दिया है। जैसे

var div = $("<div>"); 

div.promise().done(function(arg1) { 
    // Will fire right away and alert "true" 
    alert(this === div && arg1 === div); 
}); 

के लिए और अधिक जानकारी के लिए देखें: https://api.jquery.com/promise/

आस्थगित वादा async व्यवहार के करीब है:

deferred.promise()

deferred.promise() विधि को एक अतुल्यकालिक समारोह की अनुमति देता है अन्य कोड को अपने आंतरिक अनुरोध की प्रगति या स्थिति में दखल देने से रोकें। वादा केवल आस्थगित अतिरिक्त संचालकों देते हैं या राज्य (then, done, fail, always, pipe, progress, और state) के निर्धारण की आवश्यकता तरीकों, लेकिन नहीं जो कि स्थिति बदलने को उजागर करता है (resolve, reject, notify, resolveWith, rejectWith , और notifyWith)।

यदि लक्ष्य प्रदान किया गया है, तो deferred.promise() इस पर विधियों को संलग्न करेगा और फिर एक नया निर्माण करने के बजाय इस ऑब्जेक्ट को वापस कर देगा। वादा व्यवहार को किसी ऑब्जेक्ट में संलग्न करने के लिए उपयोगी हो सकता है जो पहले से मौजूद है।

यदि आप एक डिफरर्ड बना रहे हैं, तो डिफरर्ड का संदर्भ रखें ताकि इसे किसी बिंदु पर हल या अस्वीकार किया जा सके। deferred.promise() के माध्यम से केवल वादा ऑब्जेक्ट लौटें ताकि अन्य कोड कॉलबैक पंजीकृत कर सकें या वर्तमान स्थिति का निरीक्षण कर सकें।

उदाहरण:

function asyncEvent() { 
    var dfd = new jQuery.Deferred(); 

    // Resolve after a random interval 
    setTimeout(function() { 
    dfd.resolve("hurray"); 
    }, Math.floor(400 + Math.random() * 2000)); 

    // Reject after a random interval 
    setTimeout(function() { 
    dfd.reject("sorry"); 
    }, Math.floor(400 + Math.random() * 2000)); 

    // Show a "working..." message every half-second 
    setTimeout(function working() { 
    if (dfd.state() === "pending") { 
     dfd.notify("working... "); 
     setTimeout(working, 500); 
    } 
    }, 1); 

    // Return the Promise so caller can't change the Deferred 
    return dfd.promise(); 
} 

// Attach a done, fail, and progress handler for the asyncEvent 
$.when(asyncEvent()).then(
    function(status) { 
    alert(status + ", things are going well"); 
    }, 
    function(status) { 
    alert(status + ", you fail this time"); 
    }, 
    function(status) { 
    $("body").append(status); 
    } 
); 

अधिक जानकारी के लिए स्थगित वस्तु के लिए दस्तावेज़ देखें: http://api.jquery.com/category/deferred-object/

jQuery.when()

, एक या अधिक ऑब्जेक्ट के आधार पर कॉलबैक कार्यों को निष्पादित करने के लिए एक रास्ता प्रदान करता है आमतौर पर डिफरर्ड ऑब्जेक्ट्स जो असीमित घटनाओं का प्रतिनिधित्व करते हैं। उदाहरण:

$.when($.ajax("test.aspx")).then(function(data, textStatus, jqXHR) { 
    alert(jqXHR.status); // Alerts 200 
}); 
+0

यह दर्शाता है कि यह मेरे परिदृश्य के लिए कैसा दिखाई देगा? –

+0

मुझे 'बूटबॉक्स' के बारे में निश्चित नहीं है, ऐसा लगता है कि उस लाइब्रेरी में संवाद छिपाने के लिए ठीक क्लिक करने के लिए डिफ़ॉल्ट कार्रवाई है। सरल संवाद में, मैंने केवल शर्त पर संवाद छिपाकर एक ही काम किया है। –

+0

अगर मैं कॉलबैक में झूठी वापसी करता हूं, तो यह संवाद बंद नहीं करेगा –

4

आप नहीं कर सकते हैं:

यह है कि अगर मैं कुछ इस तरह कर सकते हैं महान हो जाएगा। जेएस में await के बराबर नहीं है।

आपको postForm के आमंत्रण पर झूठी वापसी करके इसे अनुकरण करना होगा और फिर AJAX कॉल से कॉलबैक-फ़ंक्शन निष्पादन पर संवाद बंद करें।

+2

काम करना चाहिए, मुझे लगता है कि हम jQuery में 'वादा' का उपयोग करके उस के बराबर अनुकरण कर सकते हैं। –

+0

हां, ऐसा लगता है कि आप कर सकते हैं, और यह मैंने कहा है कि यह कम या ज्यादा है - इसके लिए कोई भाषा समर्थन नहीं है, लेकिन jQuery के बाद स्पष्ट रूप से आपको इसे अनुकरण करने की आवश्यकता है। – fredrik

+0

मैं fredrik से सहमत हूँ; आप वास्तव में जेएस में एक ही व्यवहार का अनुकरण नहीं कर सकते हैं। सी # में, आप एक चर को कॉल के प्रतीक्षित मान पर सेट कर सकते हैं उदा। 'var name = getNameAsync(); प्रतीक्षा करें, लेकिन इससे कोई फर्क नहीं पड़ता कि आप इसे कैसे फिसलते हैं, आपको जेएस में कॉलबैक का उपयोग करना होगा। कोई बड़ा सौदा नहीं है, लेकिन यदि आपके पास एकाधिक एसिंक फ़ंक्शन हैं जो किसी अन्य कॉल के एसिंक परिणाम पर निर्भर करते हैं तो इससे गहरा घोंसला कॉल हो सकता है। जेएस में, वही कोड 'var name होगा; getName.then (newName => name = newName); ' –

7

जावास्क्रिप्ट (वर्तमान में) async/await के समतुल्य भाषा नहीं है। जावास्क्रिप्ट के लिए various promise libraries उपलब्ध हैं जो आपको Task प्रकार के बराबर समतुल्य देते हैं। यह कच्चे कॉलबैक के ऊपर एक अच्छा कदम है, लेकिन आप अभी भी सबसे सरल परिदृश्यों में अजीब घोंसले या कॉलबैक स्पेगेटी के साथ समाप्त हो जाते हैं।

जावास्क्रिप्ट ईसीएमएस्क्रिप्ट 6 ("सद्भावना") में generators शामिल होने की उम्मीद है। ईएस 6 इस वर्ष के अंत में आधिकारिक बनने के लिए ट्रैक पर है, लेकिन इससे पहले कि आप सुरक्षित रूप से यह मान सकें कि आपके उपयोगकर्ता के ब्राउज़र जेनरेटर का समर्थन करते हैं, यह शायद कुछ समय बाद होगा।

combining generators with promises द्वारा, आप एक सच्चे async/await समकक्ष प्राप्त कर सकते हैं।

1

आप Google Traceur Compiler साथ ES6 जनरेटर और yield सुविधा का उपयोग कर सकते हैं के रूप में मैं here का वर्णन किया।

ट्रेसीर टीम से some feedback है जो दर्शाता है कि यह उत्पादन की गुणवत्ता का एक साधन है। async/await के लिए इसमें experimental support भी है।

1

आप asyncawait विचार कर सकते हैं इस प्रकार है जो प्रभावी रूप से मदद से आप कोड लिखने

var foo = async (function() { 
    var resultA = await (firstAsyncCall()); 
    var resultB = await (secondAsyncCallUsing(resultA)); 
    var resultC = await (thirdAsyncCallUsing(resultB)); 
    return doSomethingWith(resultC); 
}); 
बजाय

function foo2(callback) { 
    firstAsyncCall(function (err, resultA) { 
     if (err) { callback(err); return; } 
     secondAsyncCallUsing(resultA, function (err, resultB) { 
      if (err) { callback(err); return; } 
      thirdAsyncCallUsing(resultB, function (err, resultC) { 
       if (err) { 
        callback(err); 
       } else { 
        callback(null, doSomethingWith(resultC)); 
       } 
      }); 

     }); 
    }); 
} 
0

निम्नलिखित हालांकि इस का उत्तर न मिले "क्या सी # के बराबर है में का इंतजार है जावास्क्रिप्ट? " प्रश्न, प्रश्न में कोड को आसानी से काम करने के लिए बनाया जा सकता है। bootbox.dialog समारोह एक वस्तु देता है, तो आप कोड इसलिए की तरह दिखाया गया है समायोजित कर सकते हैं:, इसका जवाब ES2017 के आगमन के साथ

function postForm() {   
    $.ajax({ 
     type: "POST", 
     url: $("#add-group").val(), 
     data: $("#form").serialize(), 
     success: function (data) { 
      // add this call to the underlying Bootstrap modal object 
      dialog.modal('hide'); 
     }, 
     error: function (XMLHttpRequest, textStatus, errorThrown) { 
      // Maybe inject an error message into the dialog? 
     } 
    }); 
} 
0

:

var dialog = bootbox.dialog({ 
    title: "Group", 
    buttons: { 
     success: { 
      label: "OK", 
      className: "btn-success", 
      callback: function() { 
       postForm(); 
       return false; // add this return here 
      } 
     } 
    } 
}); 

और फिर ajax कॉल करने के लिए समायोजित हो जाता है सवाल async/प्रतीक्षा है।
यह "कॉलबैक नरक" के लिए जेएस समाधान है। आप एसिंक फ़ंक्शन में वादा (कार्य-समकक्ष) का इंतजार कर सकते हैं।
सी # के विपरीत, एक सिंक्रोनस फ़ंक्शन में एसिंक-फ़ंक्शन को कॉल करने का कोई तरीका नहीं है।

ECMA-draft 262 या MDN नज़दीकी जानकारी के लिए देखें।

उदाहरण:

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> 
<head> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> 

    <meta http-equiv="cache-control" content="max-age=0" /> 
    <meta http-equiv="cache-control" content="no-cache" /> 
    <meta http-equiv="expires" content="0" /> 
    <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" /> 
    <meta http-equiv="pragma" content="no-cache" /> 

    <meta charset="utf-8" /> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 

    <meta http-equiv="Content-Language" content="en" /> 
    <meta name="viewport" content="width=device-width,initial-scale=1" /> 

    <meta name="google" value="notranslate" /> 


    <!-- 
    <meta name="author" content="name" /> 
    <meta name="description" content="description here" /> 
    <meta name="keywords" content="keywords,here" /> 

    <link rel="shortcut icon" href="favicon.ico" type="image/vnd.microsoft.icon" /> 
    <link rel="stylesheet" href="stylesheet.css" type="text/css" /> 
    --> 

    <title>Title</title> 

    <style type="text/css" media="all"> 
     body 
     { 
      background-color: #0c70b4; 
      color: #546775; 
      font: normal 400 18px "PT Sans", sans-serif; 
      -webkit-font-smoothing: antialiased; 
     } 
    </style> 


    <script type="text/javascript"> 
     <!-- 
     // http://localhost:57566/foobar/ajax/json.ashx 







     var ajax = {}; 
     ajax.x = function() { 
      if (typeof XMLHttpRequest !== 'undefined') { 
       return new XMLHttpRequest(); 
      } 
      var versions = [ 
       "MSXML2.XmlHttp.6.0", 
       "MSXML2.XmlHttp.5.0", 
       "MSXML2.XmlHttp.4.0", 
       "MSXML2.XmlHttp.3.0", 
       "MSXML2.XmlHttp.2.0", 
       "Microsoft.XmlHttp" 
      ]; 

      var xhr; 
      for (var i = 0; i < versions.length; i++) { 
       try { 
        xhr = new ActiveXObject(versions[i]); 
        break; 
       } catch (e) { 
       } 
      } 
      return xhr; 
     }; 

     ajax.send = function (url, callback, method, data, async) { 
      if (async === undefined) 
      { 
       async = true; 
      } 

      var x = ajax.x(); 
      x.open(method, url, async); 
      x.onreadystatechange = function() { 
       if (x.readyState == 4) { 
        callback(x.responseText) 
       } 
      }; 
      if (method == 'POST') { 
       x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); 
      } 
      x.send(data) 
     }; 

     ajax.get = function (url, data, callback, async) { 
      var query = []; 
      for (var key in data) { 
       query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key])); 
      } 
      ajax.send(url + (query.length ? '?' + query.join('&') : ''), callback, 'GET', null, async) 
     }; 

     ajax.post = function (url, data, callback, async) { 
      var query = []; 
      for (var key in data) { 
       query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key])); 
      } 
      ajax.send(url, callback, 'POST', query.join('&'), async) 
     }; 


     /////////// 



     function testAjaxCall() { 
      ajax.get("./ajax/json.ashx", null, function (bError, strMessage, iStatus) 
       { 
        console.log("args:", arguments); 

        console.log("Error:", bError); 
        console.log("Message:", strMessage); 
        console.log("Status:", iStatus); 
       } 
       , true 
      ); 

     } 
     --> 
    </script> 

</head> 
<body> 

    <script type="text/javascript"> 

     function ajaxGet(url, data) 
     { 
      var result; 

      return new Promise(function (resolve, reject) 
       { 

        ajax.get(url, data, function (bError, strMessage, iStatus) 
         { 

          // console.log("args:", arguments); 

          // console.log("Error:", bError); 
          // console.log("Message:", strMessage); 
          // console.log("Status:", iStatus); 

          result = bError; 
          resolve(result); 
         } 
         ,true 
        ); 

       } 
      ); 

     } 


     async function main() 
     { 
      var ajaxResult = await ajaxGet("./ajax/json.ashx"); 
      console.log("ajaxResult: ", ajaxResult); 
     } 

     async function lol() 
     { 
      var res = null; 

      var myPromise = new Promise(function (resolve, reject) 
      { 
       // Standard AJAX request setup and load. 
       var request = new XMLHttpRequest(); 

       // Request a user's comment from our fake blog. 
       request.open('GET', 'https://localhost:57566/ajax/json.ashx'); 

       /* 
       // Set function to call when resource is loaded. 
       // Onload same as onreadystatechange - onload added with XHR2 
       request.onload = function() 
       { 
        // internal server error/404 
        if (request.status === 200) 
        { 
         res = request.response; 
         // console.log(request.response); 
         console.log("onload- resolving promise"); 
         resolve(request.response); 
        } else 
        { 
         console.log("onload- rejectinv promise"); 
         reject('Page loaded, but status not OK.'); 
        } 
       }; 
       */ 


       request.onreadystatechange = function() 
       { 
        console.log("readystate:", request.readyState); 
        console.log("status:", request.status) 

        if (request.readyState != 4) return; 

        // XMLHttpRequest.DONE = 200, 0=cancelled 304 = redirect 
        //if (!(request.status != 200 && request.status != 304 && request.status != 0)) 
        if (request.status === 200) 
        { 
         console.log("successy") 
         resolve(request.responseText); // Success 
         return; 
        } 

        if (request.status != 200 && request.status != 0 && request.status != 304) 
        { 
         console.log('HTTP error ' + request.status); 
         // reject('Page loaded, but status not OK.'); 
         reject(new Error("Server error - Status NOK", "filename", "linenum666")); // Error 
         return; 
        } 

        if (request.status === 0) 
        { 
         console.log("cancelled:", request) 
         //resolve(null); // Cancelled, HTTPS protocol error 
         return; 
        } 

        reject(new Error("Strange error", "filename", "linenum666")); // Some Error 
       }; 

       // Set function to call when loading fails. 
       request.onerror = function() 
       { 
        // Cannot connect 
        console.log("OMG OnError"); 
        // reject('Aww, didn\'t work at all. Network connectivity issue.'); 
        reject(new Error("Aww, didn\'t work at all. Network connectivity issue.", "filename", "linenum666")); // Some Error 

       }; 


       if (!navigator.onLine) 
       { 
        console.log("No internet connection"); 
        reject("No internet connection"); 
       } 
       else 
       { 
        try 
        { 
         request.send(); 
        } 
        catch (ex) 
        { 
         console.log("send", ex.message, ex); 
        } 
       } 

      }); 

      return myPromise; 
     } 



     async function autorun() 
     { 
      console.clear(); 
      // await main(); 

      try 
      { 
       var resp = await lol(); 
       console.log("resp:", resp); 
      } 
      catch (ex) 
      { 
       console.log("foo", ex.message, ex); 
      } 



      console.log("I am here !"); 
     } 

     if (document.addEventListener) document.addEventListener("DOMContentLoaded", autorun, false); 
     else if (document.attachEvent) document.attachEvent("onreadystatechange", autorun); 
     else window.onload = autorun; 
    </script> 

</body> 
</html> 
संबंधित मुद्दे