পূর্ববর্তী ফাংশনটি সম্পূর্ণ হওয়ার পরে কোনও ফাংশন কল করুন


178

আমার নীচে জাভাস্ক্রিপ্ট কোড রয়েছে:

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable);
        function2(someOtherVariable);
    }
    else {
        doThis(someVariable);
    }
});

আমি কীভাবে নিশ্চিত করতে পারি যে এটি সম্পন্ন function2হওয়ার পরেই ডাকা হবে function1?


24
হয় function1একটি ASYNC অপারেশন সম্পাদন?
LiraNuna

8
ইয়াদ, ফাংশন 1 এ অ্যানিমেশন রয়েছে তবে ফাংশন 1 এর অ্যানিমেশনগুলি এখনও ঘটতে থাকা অবস্থায় ফাংশন 2 কার্যকর করা হবে। ফাংশন 1-এ শুরু হওয়া সমস্ত কাজ সম্পূর্ণ না হওয়া পর্যন্ত আপনি কীভাবে ফাংশন 2 অপেক্ষা করবেন?
trusktr

কেউ আমাকে ব্যাখ্যা করতে পারেন যে ফাংশন 1 সম্পূর্ণ না হওয়া পর্যন্ত ফাংশন 2 না চাওয়া নিশ্চিত করার জন্য কেন কিছু করা দরকার? এখানে কোনও অ্যাসিঙ্ক্রোনাস অপারেশন হচ্ছে না তাই ফাংশন 2 চলবে না যতক্ষণ না ফাংশন 1 কোনওভাবে সম্পূর্ণ না হওয়া পর্যন্ত এই অপারেশনটি সিঙ্ক্রোনাস is
অ্যারন

উত্তর:


204

একটি বেনামে কলব্যাক নির্দিষ্ট করুন এবং ফাংশন 1 এটি গ্রহণ করুন:

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable, function() {
          function2(someOtherVariable);
        });
    }
    else {
        doThis(someVariable);
    }
});


function function1(param, callback) {
  ...do stuff
  callback();
} 

11
+1 তবে যদি তিনি 1.5 ব্যবহার করেন তবে তিনি কেবল নতুন
ডিফার্ডস

দ্রুত প্রতিক্রিয়ার জন্য ধন্যবাদ). হ্যাঁ, ফাংশন 1 কেবল একটি সাধারণ অ্যাসিনক্রোনাস টাস্ক সম্পাদন করছে, তাই আমি বিশ্বাস করি যে আপনি ঠিক আছেন যে আমাকে একটি কলব্যাক তৈরি করতে হবে - অথবা ফিলিঙ্কল উল্লেখ করেছেন এই ডিফার্ড ব্যবসায়কে একবার দেখুন। ধন্যবাদ আবার, ছেলেরা। আমি কিছুটা ঘুম পাবো, এবং সকালে আবার এটিকে সামাল দেব।
Rrryyyaaannn

13
এই উত্তরটি সমাধান নয়। এখানে প্রমাণ হচ্ছে এটি কাজ করে না: jsfiddle.net/trusktr/M2h6e
trusktr

12
@ মাইক্রোবিনসন এখানে সমস্যা: ...do stuffএতে যদি অ্যাসিঙ্ক্রোনাসযুক্ত জিনিস থাকে তবে কী হবে ? প্রত্যাশিত হলে ফাংশন 2 এখনও চালিত হবে না। উপরের আমার মন্তব্যের উদাহরণটি দেখায় যে foo()ফাংশনটিতে অ্যাসিনক্রোনাস কোড রয়েছে bar()তাই এর সামগ্রীগুলি কার্যকর হওয়ার পরে এটি সামগ্রীতে আগুন দেয় না foo(), এমনকি $.when().then()তাদের একে একে একের পর এক কল করেও । ...do stuffআপনার কোডের সমস্ত স্টাফ কঠোরভাবে সিঙ্ক্রোনাস হলে এই উত্তরটি কেবল বৈধ nch
trusktr

1
@trusktr যে ক্ষেত্রে তোমাদের নিকটে নামিয়া প্রথম কলব্যাক ক্ষণস্থায়ী রাখা প্রয়োজন এন অ্যাসিঙ্ক্রোনাস কলের তম স্তর, তারপর আগুন callBack()পরে এন অ্যাসিঙ্ক্রোনাস কল করা হয়। যেহেতু ওপি ফাংশনে তিনি কী করছেন তা উল্লেখ না করে এটি একে এক স্তর হিসাবে অ্যাসিক্রোনাস কল হিসাবে ধরে নিয়েছে।
গুডএসপিএনডি

96

আপনি যদি jQuery 1.5 ব্যবহার করেন তবে আপনি নতুন ডিফার্ডস প্যাটার্নটি ব্যবহার করতে পারেন:

$('a.button').click(function(){
    if(condition == 'true'){
        $.when(function1()).then(function2());
    }
    else {
        doThis(someVariable);
    }
});

সম্পাদনা করুন: আপডেট ব্লগ লিঙ্ক:

রেবেকা মারফি এখানে এই সম্পর্কে একটি দুর্দান্ত রচনা আপ ছিল: http://rmurphey.com/blog/2010/12/25/deferreds- आगामी-to - jquery/


2
কিন্তু এটি কি একটি কাজের উদাহরণ? পিছিয়ে দেওয়া হচ্ছে কি? আপনি অবিলম্বে ফাংশন 1 এবং ফাংশন 2 কার্যকর করছেন। (আমি আসল মন্তব্যকারী নই))
ব্যবহারকারী 113716

10
এটি আমার পক্ষে মোটেও কাজ করে না। ফাংশন 1 এবং ফাংশন 2 উভয় একই সময়ে কার্যকর করা হয় (যেমন মানুষের চোখ দ্বারা পর্যবেক্ষণযোগ্য)। এখানে ছোট উদাহরণটি: jsfiddle.net/trusktr/M2h6e
trusktr

1
রেবেকা মারফি লেখার আগে ডিফার্ডসকে jQuery এর সাথে পরিচয় করিয়ে দেওয়ার আগে লেখা হয়েছিল এবং এটি লেখক কীভাবে এটি বাস্তবায়িত হবে বলে মনে করে তার উপর ভিত্তি করে উদাহরণ ব্যবহার করে। কীভাবে প্রকৃতপক্ষে এই বৈশিষ্ট্যটি ব্যবহার করতে হয় তা দেখতে দয়া করে jQuery এর সাইট দেখুন: api.jquery.com/jQuery.Deferred
স্পেন্সার উইলিয়ামস

1
এমনকি jQuery 1.5। বা আধুনিক কিছু দিয়েও আপনি চান না $.when(function1).then(function2);(ফাংশনটিকে কল করা প্রথম বন্ধনীগুলি ছাড়া)?
তিপিম্ম

1
এই মন্তব্যগুলি কয়েক বছর দেরী পড়া। function1একটি প্রতিশ্রুতি ফিরে উচিত। সেক্ষেত্রে এটি প্রকৃত সম্পাদিত ফাংশন হওয়া দরকার, রেফারেন্স নয়। যখন resolveসেই প্রতিশ্রুতি দেওয়া হয় তখন function2মৃত্যুদন্ড কার্যকর করা হয়। এটি সহজেই ধরে নিয়ে বোঝানো যায় যে function1এজ্যাক্স কল রয়েছে। doneকলব্যাক তারপর প্রতিশ্রুতি সমাধান হবে। আমি আশা করি এটা পরিষ্কার।
ফিলিউঙ্কল

46

এটা চেষ্টা কর :

function method1(){
   // some code

}

function method2(){
   // some code
}

$.ajax({
   url:method1(),
   success:function(){
   method2();
}
})

37

এই উত্তরটি ব্যবহার করে promises, মানকটির একটি জাভাস্ক্রিপ্ট বৈশিষ্ট্য ECMAScript 6। যদি আপনার টার্গেট প্ল্যাটফর্ম সমর্থন না করে promisesতবে এটি প্রোমিসজেসের সাথে পলিফিল করুন

প্রতিশ্রুতিগুলি জাভাস্ক্রিপ্টে অ্যাসিক্রোনাস অপারেশন পরিচালনা করার জন্য একটি নতুন (এবং অনেক ভাল) উপায়:

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable).then(function() {
            //this function is executed after function1
            function2(someOtherVariable);
        });
    }
    else {
        doThis(someVariable);
    }
});


function function1(param, callback) {
    return new Promise(function (fulfill, reject){
        //do stuff
        fulfill(result); //if the action succeeded
        reject(error); //if the action did not succeed
    });
} 

এটি এই সাধারণ উদাহরণের জন্য একটি গুরুত্বপূর্ণ ওভারহেডের মতো মনে হতে পারে তবে আরও জটিল কোডের জন্য এটি কলব্যাকগুলি ব্যবহার করার চেয়ে অনেক ভাল। আপনি একাধিক thenবিবৃতি ব্যবহার করে একাধিক অ্যাসিনক্রোনাস কল সহজেই চেইন করতে পারেন :

function1(someVariable).then(function() {
    function2(someOtherVariable);
}).then(function() {
    function3();
});

আপনি সহজেই jQuery ডিফার্ডস মোড়ানো করতে পারেন (যা $.ajaxকল থেকে ফিরে আসে ):

Promise.resolve($.ajax(...params...)).then(function(result) {
    //whatever you want to do after the request
});

@ চারিলিএফএফএল যেমন উল্লেখ করেছেন, jqXHRঅবজেক্টটি ইন্টারফেস $.ajax()প্রয়োগ করে ফিরিয়ে দিয়েছে Promise। সুতরাং এটিতে একটি আবদ্ধ করা আসলে প্রয়োজন হয় না Promise, এটি সরাসরি ব্যবহার করা যেতে পারে:

$.ajax(...params...).then(function(result) {
    //whatever you want to do after the request
});

Promise.resolveমোড়ানো $.ajaxযেহেতু বিরোধী প্যাটার্ন $.ajaxআয় thennable প্রতিশ্রুতি
charlietfl

@ চর্লিটএফএল তবে এটি প্রকৃত নয় Promise, এটি কেবল ইন্টারফেস প্রয়োগ করে। আমি নিশ্চিত না যে Promiseএটির thenপদ্ধতিতে বাস্তব পাস করার সময় এটি কীভাবে আচরণ করে , বা Promise.allযদি একটি jqXHRএবং Promiseএটি পাস করা হয় তবে কী করবে। তার জন্য আমাকে আরও পরীক্ষা করা দরকার। তবে ইঙ্গিতটির জন্য আপনাকে ধন্যবাদ, আমি এটি উত্তরে যুক্ত করব!
ডোমসি

আসলে jQuery সংস্করণ 3+ এ প্রতিশ্রুতি A + সম্মতিযুক্ত। অনিয়মহীন $.ajax.thenনতুন নয়
22:58

21

বা কোনও ফাংশন শেষ হলে আপনি একটি কাস্টম ইভেন্ট ট্রিগার করতে পারেন, তারপরে এটি নথিতে আবদ্ধ করুন:

function a() {
    // first function code here
    $(document).trigger('function_a_complete');
}

function b() {
    // second function code here
}

$(document).bind('function_a_complete', b);

এই পদ্ধতিটি ব্যবহার করে, ফাংশন 'বি' কেবল 'এ' এর পরে 'ফাংশন' চালায়, কারণ ট্রিগারটি তখনই উপস্থিত থাকে যখন ফাংশন একটি সম্পাদন শেষ হয় uting


"JQuery 1.7 হিসাবে, .on () পদ্ধতিটি কোনও নথিতে ইভেন্ট হ্যান্ডলার সংযুক্ত করার জন্য পছন্দসই পদ্ধতি" " api.jquery.com/bind
CodeVirtuoso

3

এটি ফাংশন 1 কী করছে তার উপর নির্ভর করে।

যদি ফাংশন 1 কোনও ডিভ মান বা কিছু আপডেট করার মতো কিছু সাধারণ সিঙ্ক্রোনাস জাভাস্ক্রিপ্ট করছে, তবে ফাংশন 2 সম্পূর্ণ হয়ে যাওয়ার পরে ফাংশন 2 চালু হবে।

যদি ফাংশন 1 কোনও এজেএক্স কলের মতো একটি অ্যাসিঙ্ক্রোনাস কল করছে, আপনার একটি "কলব্যাক" পদ্ধতি তৈরি করতে হবে (বেশিরভাগ অ্যাজাক্স এপিআই এর একটি কলব্যাক ফাংশন প্যারামিটার রয়েছে)। তারপরে কলব্যাকে ফাংশন 2 কল করুন। উদাহরণ:

function1()
{
  new AjaxCall(ajaxOptions, MyCallback);
}

function MyCallback(result)
{
  function2(result);
}


2

পদ্ধতি 2, 3, 4 পরে যদি পদ্ধতি 1 প্রয়োগ করতে হয় তবে নিম্নলিখিত কোড স্নিপেট জাভাস্ক্রিপ্টে ডিফার্ড অবজেক্ট ব্যবহার করে এর সমাধান হতে পারে।

function method1(){
  var dfd = new $.Deferred();
     setTimeout(function(){
     console.log("Inside Method - 1"); 
     method2(dfd);	 
    }, 5000);
  return dfd.promise();
}

function method2(dfd){
  setTimeout(function(){
   console.log("Inside Method - 2"); 
   method3(dfd);	
  }, 3000);
}

function method3(dfd){
  setTimeout(function(){
   console.log("Inside Method - 3"); 	
   dfd.resolve();
  }, 3000);
}

function method4(){   
   console.log("Inside Method - 4"); 	
}

var call = method1();

$.when(call).then(function(cb){
  method4();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


0

ফাংশন 1 যদি এমন কিছু সিঙ্ক ফাংশন হয় যা আপনি একটি অ্যাসিঙ্ক হিসাবে রূপান্তর করতে চান কারণ এটি সম্পূর্ণ হতে কিছুটা সময় নেয়, এবং কলব্যাক যোগ করতে আপনার এতে কোনও নিয়ন্ত্রণ নেই:

function function1 (someVariable) {
    var date = Date.now ();
    while (Date.now () - date < 2000);      // function1 takes some time to complete
    console.log (someVariable);
}
function function2 (someVariable) {
    console.log (someVariable);
}
function onClick () {
    window.setTimeout (() => { function1 ("This is function1"); }, 0);
    window.setTimeout (() => { function2 ("This is function2"); }, 0);
    console.log ("Click handled");  // To show that the function will return before both functions are executed
}
onClick ();

আউটপুটটি হবে:

Click handled

... এবং 2 সেকেন্ড পরে:

This is function 1
This is function 2

এটি কাজ করে কারণ উইন্ডো.সেটটাইমআউট () কল করা জেএস রুটাইন টাস্ক লুপে একটি টাস্ক যুক্ত করবে, যা একটি অ্যাসিঙ্ক কলটি করে এবং জেএস রানটাইমের "রান-টু-সমাপ্তি" এর মূল নীতিটি অনক্লিক () নিশ্চিত করে যে এটি শেষ হওয়ার আগে কখনও বাধা হয় না।

লক্ষ্য করুন যে এটি কোড হিসাবে বুঝতে অসুবিধা হিসাবে মজাদার ...

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.