2012-07-18 19 views
13

मैं घटनाओं की एक सरल श्रृंखला:चेन वादे

  1. एक मेटाडाटा तालिका में कॉलम जाओ (async)
  2. लोड चयनित स्तंभ (async)
  3. सूची प्रस्तुत करना

मैं केवल इन कार्यों को चेन करता था, प्रत्येक इसे पूरा होने पर अगली कॉलिंग करता था। हालांकि, यह बहुत स्पष्ट नहीं है कि क्या हो रहा है (getColumnsFromMeta पर नज़र डालने के परिणामस्वरूप)। तो स्पष्टता और कोड पुन: उपयोग के हित में मैं JQueryPromises का उपयोग करके इन्हें दोबारा प्रतिक्रिया देना चाहता हूं। मैंने पहले वादे का इस्तेमाल किया है। लेकिन मैं दो से अधिक श्रृंखला कैसे करूं?

var getColumnsFromMeta = function(id) 
{ 
    var sql, 
     dfd; 

    dfd = $.Deferred(); 

    var onSuccess = function(tx, result) 
    { 
     var columns = []; 

     for (var i = 0; i < result.rows.length; i++) 
     { 
      columns.push(result.rows.item(i).Column); 
     } 

     dfd.resolve(columns); 
    }; 

    var onError = function(tx, error) 
    { 
     dfd.reject(error); 
    }; 

    sql = "SELECT Column FROM Meta WHERE id = ?"; 

    database.query(sql, [id], onSuccess, onError); 

    return dfd.promise(); 
}; 

उत्तर

27
कुछ

यह होना चाहिए की तरह: getColumnsFromMeta().then(loadSourceFromDatabase /*some arguments*/) //.then(renderList)?;

यहाँ getColumnsFromMeta का एक उदाहरण है

function getColumnsFromMeta() 
{ 
    var d = $.Deferred(); 

    // retrieve data in async manner and perform 
    // d.resolve(columns); 

    return d.promise(); 
} 

function loadSelectedColumns(columns) 
{ 
    var d = $.Deferred(); 

    // retrieve data in async manner and perform 
    // d.resolve(data); 

    return d.promise(); 
} 

function render(data) 
{ 
    // render your data 
} 

getColumnsFromMeta().pipe(loadSelectedColumns).pipe(render); 

http://jsfiddle.net/zerkms/xYDbm/1/ - यहाँ एक काम नमूना

http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/ है - इस लेख है मुझे वास्तव में वादे के बारे में पसंद है

+0

त्वरित उत्तर के लिए धन्यवाद यह बहुत अच्छा काम करता है! और लेख के लिए धन्यवाद, यह अच्छा लग रहा है। एक अतिरिक्त प्रश्न के रूप में: क्या विभिन्न चरणों में पाइप पर .done/.always आदि को चेन करना संभव है? – JonWells

+0

@CrimsonChin: हाँ। पीएस: मुझे एक सेकंड दें, jsfiddle एक पल में किया जाएगा – zerkms

+0

@CrimsonChin: हाँ, आप उनमें से किसी भी का उपयोग कर सकते हैं, जब तक कि 'पाइप() 'रिटर्न स्थगित हो। पीएस: मैंने जोड़ा jsfiddle उदाहरण – zerkms

4

ज़र्केम्स के जवाब ने मुझे कुछ विचारों के बाद मदद की। अगर मैं पूर्ण संदर्भ वाला उदाहरण उपयोगी हूं तो मैं यहां पोस्ट करने जा रहा हूं।

/** 
* takes a list of componentIDs to load, relative to componentRoot 
* returns a promise to the map of (ComponentID -> componentCfg) 
*/ 
function asyncLoadComponents (componentRoot, components) { 

    var componentCfgs = {}; 

    function asyncLoadComponentCfg(component) { 
     var url = _.sprintf("%s/%s", componentRoot, component); 
     var promise = util.getJSON(url); 
     promise.done(function(data) { 
      componentCfgs[component] = data; 
     }); 
     return promise; 
    } 

    var promises = _.map(components, asyncLoadComponentCfg); 
    var flattenedPromise = $.when.apply(null, promises); 
    var componentCfgPromise = flattenedPromise.pipe(function() { 
     // componentCfgs is loaded now 
     return $.Deferred().resolve(componentCfgs).promise(); 
    }); 

    return componentCfgPromise; 
} 


var locale = 'en-US'; 
var componentRoot = '/api/components'; 
var components = ['facets', 'header', 'DocumentList']; 
$.when(asyncLoadComponents(componentRoot, components)).done(function(componentCfgs) { 
    buildDocumentListPage(locale, componentCfgs) 
}); 
संबंधित मुद्दे