2008-10-18 12 views
17

मैं एक जावास्क्रिप्ट एपीआई के साथ काम कर रहा हूं जहां अधिकांश कार्य असीमित हैं। एपीआई WebKit JavaScript Database API है जो SQLite3 डेटाबेस में हेरफेर करने के लिए कार्यक्षमता के सबसेट के लिए बाध्यकारी है। मैं ब्लॉक एसिंक को अवरुद्ध करने और उत्तरदायी यूजर इंटरफेस प्रदान करने के लिए डिजाइन निर्णय को समझता हूं। मेरी स्थिति में मुझे पता है कि async API कॉल का मेरा उपयोग तेजी से निष्पादित होगा। चूंकि यह मामला है कि मैं अपने डेवलपर्स को एक क्लीनर और आसान रैपर एपीआई का उपयोग करना चाहता हूं जो सिंक्रोनस कॉल को मजबूर करता है।सिंक्रोनस बनाने के लिए एक असीमित जावास्क्रिप्ट फ़ंक्शन को लपेटने के लिए पैटर्न

यहाँ async कॉल है

db.executeSql(sqlStatement, function(result) { 
    // do something with result 
}); 

और यहाँ मैं

var result = dbWrapper.executeSql(sqlStatement); 
// do something with result 

वहाँ एक डिजाइन पैटर्न/तरीका यह है है ऐसा करने में सक्षम होना चाहते हैं क्या है? एक लिखित या लिंक कोड से जुड़ा हुआ है। आईफोन पर लक्षित प्लेटफार्म/ब्रोसर मोबाइल सफारी है। अगर आप jQuery अजाक्स का उपयोग कर रहे

आप

+0

क्योंकि मुझे लगता है यह कम से कम धागा समर्थन के बिना संभव नहीं (है, जो सफारी के लिए जा रहा नहीं है यह, यदि आप एक जवाब मिलता है देखने के लिए दिलचस्प हो जाएगा आपको देना)। –

उत्तर

1

धन्यवाद: $ .ajax()

आप झूठी, को asynch की विशेषता सेट कर सकते हैं और फिर आप सर्वर के लिए एक सिंक ajax अनुरोध करना होगा ।

+2

मैंने देखा कि जिस तरह से jQuery ने एसिंक बूलियन के उपयोग के साथ $ .ajax() फ़ंक्शन को लागू किया है, लेकिन यह पता चला है कि यह केवल "मूल" कोड में लागू XMLHttpRequest.open फ़ंक्शन के माध्यम से async param को पास करता है (जेएस नहीं) और इसलिए तुल्यकालिक व्यवहार को मजबूर कर सकते हैं। – pfeilbr

1

हम जीडब्ल्यूटी आरपीसी का उपयोग कर रहे हैं जिसमें एसिंक एपीआई भी है। समाधान है कि हम वर्तमान धारावाहिक में कई async कॉल करने के लिए उपयोग कर रहे हैं कॉल श्रृंखलन है:

callA(function(resultA) { 
    callB(resultA, function(resultB) { 
     callC(); //etc. 
    }); 
}); 

यह नेस्टेड दृष्टिकोण को प्राप्त होता है कि आप क्या चाहते हैं लेकिन यह अत्यधिक शब्द और नए लोगों के लिए पढ़ने के लिए कठिन है।

callStack = [ 
    callA(), 
    callB(), 
    callC() 
]; 

callStack.execute(); 

फिर callstack का प्रबंधन होगा::

  1. धारावाहिक में कॉल लागू दृष्टिकोण है कि हम जांच की है कॉल है कि हम एक ढेर को बनाने की जरूरत है जोड़ने और उन्हें क्रम में निष्पादित हो रहा है में से एक (यानी पहले उदाहरण में तारों)
  2. परिणाम को एक कॉल से अगले तक परिणाम पास करना।

हालांकि, क्योंकि जावा में फ़ंक्शन संदर्भ नहीं हैं, इसलिए कॉल स्टैक पर प्रत्येक कॉल को अज्ञात वर्ग की आवश्यकता होगी ताकि हमने इस तरह के समाधान को कम कर दिया हो। हालांकि, आपको जावास्क्रिप्ट में और अधिक सफलता हो सकती है।

शुभकामनाएं!

10

क्षमा करें, जावास्क्रिप्ट एसिंक्रोनस चीजें सिंक्रोनस या इसके विपरीत कार्य करने के लिए भाषा प्राइमेटिव (जैसे धागे या कोरआउट) प्रदान नहीं करता है।

आप आम तौर पर केवल निष्पादन का एक धागा प्राप्त करते हैं, इसलिए आप टाइमर या XMLHttpRequest readystatechange से कॉलबैक नहीं प्राप्त कर सकते हैं जब तक अनुरोध के निर्माण की ओर अग्रसर कॉल के ढेर को पूरी तरह से सुलझाया नहीं जाता है।

तो संक्षेप में, आप वास्तव में ऐसा नहीं कर सकते हैं; आपके द्वारा लिंक किए गए वेबकिट पेज पर नेस्टेड क्लोजर के साथ दृष्टिकोण एकमात्र तरीका है जिसे मैं इस स्थिति में कोड को पठनीय बनाने के बारे में जानता हूं।

*: कुछ अस्पष्ट स्थितियों तुम्हारी मदद नहीं होगा और आम तौर पर कीड़े

माना जाता है को छोड़कर
+1

यह सही समझ में आता है। स्पष्ट स्पष्टीकरण के लिए धन्यवाद। – pfeilbr

+1

अपडेट 2014, जावास्क्रिप्ट में अब इस भाषा से निपटने के लिए भाषा प्राइमेटिव्स (कोरआउट) शामिल हैं, हालांकि समर्थन वर्तमान में नोडजेएस, क्रोम और फ़ायरफ़ॉक्स के नीचे क्रोम तक सीमित है। https://github.com/petkaantonov/bluebird/blob/master/API.md#promisecoroutinegeneratorfunction-generatorfunction--- कार्यक्षमता –

4

आप की तरह कुछ की कोशिश कर सकते हैं:

function synch() 
{ 
    var done = false; 
    var returnVal = undefined; 

    // asynch takes a callback method 
    // that is called when done 
    asynch(function(data) { 
     returnVal = data; 
     done = true; 
    }); 

    while (done == false) {}; 
    return returnVal; 
} 

लेकिन उस की अवधि के लिए आपके ब्राउज़र फ्रीज कर सकते हैं asynch विधि ...

या कथात्मक जावास्क्रिप्ट पर एक नज़र डालें: कथात्मक जावास्क्रिप्ट जावास्क्रिप्ट भाषा के लिए एक छोटा सा विस्तार है जो असीमित घटना कॉलबैक के लिए अवरुद्ध क्षमताओं को सक्षम बनाता है। यह अतुल्यकालिक कोड ताज़ा पढ़ने योग्य और समझदार बनाता है।

http://neilmix.com/narrativejs/doc/index.html

माइक

+3

जावास्क्रिप्ट में धागे नहीं हैं, यह कभी काम नहीं करेगा। एक बार 'लूप' शुरू हो जाने के बाद, यह कभी खत्म नहीं होगा। – naomik

+0

आप सही हैं, कुछ वर्षों के बाद खुद को पढ़ना मुझे मूर्खतापूर्ण महसूस करता है;) –

+0

इसे अपने ऊपर मत मारो। मैंने वास्तव में सोचा कि यह मेरे लिए कोशिश करने से पहले भी काम करेगा ^।^ – naomik

0

यह वास्तव में डाटाबेस क्वेरी के तुल्यकालिक आपरेशन को लागू नहीं है, लेकिन यह आसान प्रबंधन के लिए मेरे समाधान था। मूल रूप से कॉलबैक फ़ंक्शन को कॉलबैक फ़ंक्शन के रूप में उपयोग करें, और परिणाम तर्क के लिए परीक्षण करें। यदि फ़ंक्शन को परिणाम प्राप्त होते हैं, तो यह उन्हें पार्स करता है, यदि नहीं, तो यह क्वेरी विधि में कॉलबैक के रूप में खुद को भेजता है।

render: function(queryResults){ 
    if (typeof queryResults != 'undefined'){ 
    console.log('Query completed!'); 
    //do what you will with the results (check for query errors here) 

    } else { 
    console.log('Beginning query...'); 
    this.db.read(this.render); //db.read is my wrapper method for the sql db, and I'm sending this render method as the callback. 
    } 
} 
+0

आपके पास एक अलग कॉलबैक फ़ंक्शन भी हो सकता है। कॉलर फ़ंक्शन को भी कॉलबैक फ़ंक्शन बस स्थिति को भ्रमित कर रहा है – Dean

8

स्ट्रैटिफाइडजेएस आपको बिल्कुल ऐसा करने की अनुमति देता है।

वहाँ कैसे ब्राउज़र भंडारण पर इसे लागू करने के बारे में भी एक लेख है: http://onilabs.com/blog/stratifying-asynchronous-storage

और इस स्तरीकृत JavaScript लाइब्रेरी यह https://gist.github.com/613526

का उपयोग करता है, उदाहरण के प्रकार है:

var db = require("webdatabase").openDatabase("CandyDB", ...); 
try { 
    var kids = db.executeSql("SELECT * FROM kids").rows; 
    db.executeSql("INSERT INTO kids (name) VALUES (:name);", [kids[0]]); 
    alert("done"); 
} catch(e) { 
    alert("something went wrong"); 
} 

शायद थोड़ा देर हो चुकी है, लेकिन तकनीक तब मौजूद नहीं थी;)

+0

गिटहब स्रोत से लिंक: https://github.com/onilabs/stratifiedjs –

0

मुझे यकीन नहीं है अगर यह सही जगह है लेकिन मैं यहां फ़ायरफ़ॉक्स में सिंक्रोनस कॉल करने के उत्तर खोजने के लिए कैम हूं। समाधान पहले से ही बदले में कॉलबैक को हटाने और प्रत्यक्ष कॉल करने के लिए होगा। यह है कि मैं क्या मिल गया था और मेरे समाधान है synchronous call back with rest service

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