2010-05-26 10 views
14

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

बेशक, बदसूरत तरीका है:

execAll : function(callBack) { 
     asynch1(function() { 
      asynch2(function() { 
       ... 
       asynchN(function() { 
        callBack(); 
       }) 
      }) 
     }); 
    } 

लेकिन मुझे पता है कि बेहतर तरीके यह करने के लिए कर रहे हैं। सहजता से मैं पता लगाऊंगा कि अंतिम कॉलबैक को कॉल करने के लिए सभी कॉल बैक को काउंटर के साथ बुलाया गया था।

मुझे लगता है कि यह एक आम डिजाइन पैटर्न है, इसलिए यदि किसी को सही दिशा में मुझे बिंदु सकता है ...

अग्रिम धन्यवाद!

उत्तर

20

इस

var callback = (function(){ 
    var finishedCalls = 0; 
    return function(){ 
     if (++finishedCalls == 4){ 
      //execute your action here 
     } 
    }; 
})(); 

बस अपने सभी तरीकों को यह कॉलबैक गुजरती हैं, और एक बार यह 4 बार बुलाया गया है यह निष्पादित करेंगे आसान है।

आप इस के लिए कारखाने का उपयोग करना चाहते हैं तो आप क्या कर सकते हैं निम्नलिखित

function createCallback(limit, fn){ 
    var finishedCalls = 0; 
    return function(){ 
     if (++finishedCalls == limit){ 
      fn(); 
     } 
    }; 
} 


var callback = createCallback(4, function(){ 
    alert("woot!"); 
}); 


async1(callback); 
async2(callback); 
async3(callback); 
async4(callback); 
+1

और यदि कोई ऐसा पैटर्न मौजूद है, तो यह है। –

+0

धन्यवाद बहुत सीन, यह आसान था, और अपना जवाब देखने से पहले अपने पहले समाधान की तरह कुछ लागू करें। लेकिन मुझे आपके कॉलबैक फैक्ट्री को और अधिक पसंद है, यह बहुत ही सुरुचिपूर्ण है, मैं इसका उपयोग करूंगा ;-) – Samuel

+0

और यदि यह एक पैटर्न है, तो इसका नाम होना चाहिए। सुझाव ?! – ThomasH

8

मैं कुछ async उपयोगिताओं जो आपके लिए उपयोगी हो सकता है लिखा है, आप के रूप में अपने उदाहरण लिखने के लिए अनुमति देता है:

function(callback) { 
    async.series([ 
     asynch1(), 
     asynch2(), 
     ... 
     asynchN() 
    ], callback); 
} 

या, यदि आप, समानांतर में उन्हें चलाने के लिए के रूप में चाहता था:

function(callback) { 
    async.parallel([ 
     asynch1(), 
     asynch2(), 
     ... 
     asynchN() 
    ], callback); 
} 

अन्य उपयोग का भार कर रहे हैं async मानचित्र की तरह ful कार्य/बहुत कम हो:

http://caolanmcmahon.com/async.html

आशा है कि मदद करता है!

2

आपको एसिंक्रोनस विधियों के लिए डिफरर्ड पैटर्न का उपयोग करने पर विचार करना चाहिए। आप से इस StackOverflow सवाल और जवाब और अधिक जानकारी प्राप्त कर सकते हैं:

What are the differences between Deferred, Promise and Future in JavaScript?

jnewman से चिह्नित जवाब वास्तव में अच्छा था!

उम्मीद है कि इससे मदद मिलती है।

0

वादे इस प्रबंधन में सहायता कर सकते हैं। दो सामान्य परिदृश्य हैं - समांतर और धारावाहिक। समानांतर Promise.all() का उपयोग करके पूरा किया जा सकता है, धारावाहिक अधिक जटिल है - कार्य बी केवल तभी शुरू हो सकता है जब कार्य ए किया जाता है।

// returns a promise that resolves as the task is done 
const wrap = (fn, delay) => new Promise(resolve => setTimeout(_ => resolve(fn()), delay)); 
const task = (fn, delay) => delay ? wrap(fn, delay) : Promise.resolve(fn()); 

// given a list of promises, execute them one by one. 
const sequence = async l => l.reduce(async (a, b) => [].concat(await a, await b)); 

const tasks = [ 
    task(_ => console.log("hello world")), 
    task(_ => console.log("hello future"), 1000) 
]; 

sequence(tasks).then(_ => console.log("all done")); 

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

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