2012-11-30 12 views
16

को देखते हुए इन कार्यों:मैं jQuery 1.8.x में स्थगित कार्यों के अनुक्रम को कैसे श्रृंखलाबद्ध करूं?

function func1() { 
    var dfd = $.Deferred(); 

    setTimeout(function() { 
    dfd.resolve('Password'); 
    }, 1000); 

    return dfd.promise(); 
} 

function func2(message) { 
    var dfd = $.Deferred(); 

    setTimeout(function() { 
    if (message == 'Password') { 
     dfd.resolve('Hello World'); 
    } 
    }, 1000); 

    return dfd.promise(); 
} 

मैं निम्नलिखित करने के लिए एक बेहतर तरीका खोजने के लिए चाहते हैं। ध्यान दें यह jQuery 1.8.x का उपयोग कर रहा है।

var promise = func1(); 

promise.done(function(message1) { 

    var promise2 = func2(message1); 

    promise2.done(function(message2) { 
    alert(message2); 
    }); 
}); 

कोई विचार? मैंने सोचा कि jQuery # पाइप या #then का उपयोग करना काम करेगा लेकिन मैं इसे समझ नहीं सकता। यहां खेलने के लिए एक पहेली है: http://jsfiddle.net/Z7prn/

उत्तर

34

यह जटिल नहीं है (या तो .then या .pipe का उपयोग करें, वे दोनों jQuery 1.8 के बाद से समान हैं)।

promise.then(func2).done(function(message) { 
    alert(message); 
}); 

func2 के बाद से रिटर्न एक नई आस्थगित वस्तु, .done कॉलबैक बजाय उस से जुड़ी है।

DEMO

+1

मैं प्यार करता हूँ जब लोग इस तरह के संक्षिप्त रूप से चीजों को समझाने। समझने में आसान और – tim

+1

का पालन करें नोट: '.then' का उपयोग करें क्योंकि .pipe' को jQuery 1.8 ([docs] (http://api.jquery.com/deferred.pipe/) में बहिष्कृत किया गया है) – nhylated

-2

उपयोग JQuery.when()। यह वही है जो आप स्थगित की सरणी को श्रृंखलाबद्ध करना चाहते हैं और जब पूरा हो जाता है तो एक फ़ंक्शन चलाएं।

अद्यतन 2017 (downvotes देखने के बाद):

क्या ओ पी चाहता था उसके कोड वादों क्रमिक रूप से चलाने के लिए की एक बेहतर संस्करण था। यहाँ मेरी संस्करण $.when उपयोग कर रहा है:

function func1() { 
 
    var dfd = $.Deferred(); 
 

 
    setTimeout(function() { 
 
    dfd.resolve('Password'); 
 
    }, 1000); 
 

 
    return dfd.promise(); 
 
} 
 

 
function func2(message) { 
 
    var dfd = $.Deferred(); 
 

 
    setTimeout(function() { 
 
    if (message == 'Password') { 
 
     dfd.resolve('Hello World'); 
 
    } 
 
    }, 1000); 
 

 
    return dfd.promise(); 
 
} 
 

 
// ~~~~~~~~~~ using $.when here ~~~~~~~~~~~~ 
 

 
$.when(func1()).then(function(result1) { 
 
    $.when(func2(result1)).then(function(result2) { 
 
     alert(result2); 
 
    }) 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>

+5

वे नहीं हैं जंजीर - वे एकत्र किए जाते हैं। डिफर्स की सरणी 'एक बार में' निकाल दी जाती है, और जब() कॉलबैक निकाल दिया जाता है तो सब कुछ किया जाता है। फिर(), दूसरी तरफ, जंजीर 1() को func2() आदि से पहले हल किया जाना चाहिए। –

+0

@DesignbyAdrian आप ओपी के सवाल को अलग तरीके से क्यों समझते हैं ?! आप अपना पोस्ट कोड चला सकते हैं या शीर्षक पढ़ सकते हैं और देख सकते हैं कि वह * चाहता है * उन्हें _chain_। वह सिर्फ एक बेहतर तरीका का उपयोग करके दूसरी छीनने के लिए एक रास्ता तलाश रहा है और यही मैंने उल्लेख किया है और अभी एक उदाहरण जोड़ा है। मेरा स्निपेट का आउटपुट उसके जैसा ही है (जैसा वह चाहता था) 3 एलओसी में। – Aidin

5

मैं एक ऐसी ही उपयोग के मामले थी, इसलिए मुझे लगता है कि यह आप बाहर की मदद करनी चाहिए।

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

/असफल हैंडलर हस्ताक्षर (सरणी < संदर्भ>) समारोह (सरणी < वस्तु {अस्वीकार कर दिया | समाधान किया गया: तर्क}>) कर रहे हैं किया, जहां संदर्भ प्रत्येक resolveWith/rejectWith कॉल के संदर्भ है, या प्रश्न में स्थगित, और तर्क तर्क सेट है जो संकल्प/अस्वीकृति में पारित किया गया था।

(function ($) { 
    "use strict"; 
    var copy = function (a) { 
     return Array.prototype.slice.call(a); 
    }; 

    /** 
     Handle a sequence of methods, stopping on failure by default 
     @param Array<Function> chain List of methods to execute. Non-deferred return values will be treated as successful deferreds. 
     @param Boolean continueOnFailure Continue executing even if one of the returned deferreds fails. 
     @returns Deferred 
    */ 
    $.sequence = function (chain, continueOnFailure) { 
     var handleStep, handleResult, 
      steps = copy(chain), 
      def = new $.Deferred(), 
      defs = [], 
      results = []; 
     handleStep = function() { 
      if (!steps.length) { 
       def.resolveWith(defs, [ results ]); 
       return; 
      } 
      var step = steps.shift(), 
       result = step(); 
      handleResult(
       $.when(result).always(function() { 
        defs.push(this); 
       }).done(function() { 
        results.push({ resolved: copy(arguments) }); 
       }).fail(function() { 
        results.push({ rejected: copy(arguments) }); 
       }) 
      ); 
     }; 
     handleResult = continueOnFailure ? 
       function (result) { 
        result.always(function() { 
         handleStep(); 
        }); 
       } : 
       function (result) { 
        result.done(handleStep) 
         .fail(function() { 
          def.rejectWith(defs, [ results ]); 
         }); 
       }; 
     handleStep(); 
     return def.promise(); 
    }; 
}(this.jQuery)); 

उपयोग की एक साधारण उदाहरण: http://jsfiddle.net/rG9rA/

function func1() { 
    var dfd = $.Deferred(); 

    setTimeout(function() { 
    dfd.resolve('Password'); 
    }, 1000); 

    return dfd.promise(); 
} 

function func2(message) { 
    var dfd = $.Deferred(); 

    setTimeout(function() { 
    if (message == 'Password') { 
     dfd.resolve('Hello World'); 
    } 
    }, 1000); 

    return dfd.promise(); 
} 

    $.sequence([func1, func2, function() { alert('done'); }]); 
+0

अच्छा। मैंने कॉल के बीच एक वैकल्पिक "देरी" जोड़ा, अगर किसी बाहरी कोड को घटनाओं को व्यवस्थित करने की आवश्यकता होती है (मैं नॉकआउट का उपयोग करता हूं) –

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