চালিয়ে যাওয়ার আগে কোনও ফাংশন শেষ হওয়ার জন্য সঠিকভাবে অপেক্ষা করতে হবে?


187

আমার দুটি জেএস ফাংশন রয়েছে। একজন অন্যজনকে ডাকে। কলিং ফাংশনের মধ্যে, আমি অন্যটিকে কল করতে চাই, সেই ফাংশনটি শেষ হওয়ার জন্য অপেক্ষা করুন, তারপরে চালিয়ে যান। সুতরাং, উদাহরণস্বরূপ / সিউডো কোড:

function firstFunction(){
    for(i=0;i<x;i++){
        // do something
    }
};

function secondFunction(){
    firstFunction()
    // now wait for firstFunction to finish...
    // do something else
};

আমি এই সমাধানটি নিয়ে এসেছি, তবে জানি না এটি এটির কোনও দুর্দান্ত উপায় কিনা।

var isPaused = false;

function firstFunction(){
    isPaused = true;
    for(i=0;i<x;i++){
        // do something
    }
    isPaused = false;
};

function secondFunction(){
    firstFunction()
    function waitForIt(){
        if (isPaused) {
            setTimeout(function(){waitForIt()},100);
        } else {
            // go do that thing
        };
    }
};

এটা কি বৈধ? এটি পরিচালনা করার জন্য আরও কি মার্জিত উপায় আছে? সম্ভবত jQuery সঙ্গে?


11
firstFunctionঠিক কী করে যা এটি অবিচ্ছিন্ন করে তোলে? যে কোনও উপায়ে - প্রতিশ্রুতি সম্পর্কে পরীক্ষা করুন
zerkms

প্রথম ফাংশনটি সেকেন্ডের দশম দশকে স্কোর ক্লকটি দ্রুত আপডেট করে। যা ... এটি ভাবতে আসুন, আমি মনে করি আমরা প্রাক-গণনা করতে পারি এবং তারপরে সেটটাইমআউটের মাধ্যমে ম্যানুয়ালি দ্বিতীয় ফাংশন কলটি বিরতি দিতে পারি। এটি বলেছিল, আমি এখনও অন্য কোথাও বিরতি দেওয়ার ক্ষমতা দেখতে পাচ্ছি।
ডিএ

আপনার কোনও বিরতি লাগবে না - গুগল
জ্যাকোরিতে

@ জারকামস প্রতিশ্রুতি আকর্ষণীয় দেখায়! এখনও ব্রাউজার সমর্থন অনুসন্ধান করছে ...
ডিএ।

1
আমারও একই রকম সমস্যা।
ভ্যাপার ওয়াশমেড

উত্তর:


140

এর মতো অ্যাসিনক্রোনাস কাজের সাথে মোকাবিলা করার একটি উপায় হ'ল কলব্যাক ফাংশন ব্যবহার করা, যেমন:

function firstFunction(_callback){
    // do some asynchronous work
    // and when the asynchronous stuff is complete
    _callback();    
}

function secondFunction(){
    // call first function and pass in a callback function which
    // first function runs when it has completed
    firstFunction(function() {
        console.log('huzzah, I\'m done!');
    });    
}

@ জনাকা পুষ্পকুমারার পরামর্শ অনুসারে, আপনি এখন একই জিনিস অর্জন করতে তীর ফাংশন ব্যবহার করতে পারেন। উদাহরণ স্বরূপ:

firstFunction(() => console.log('huzzah, I\'m done!'))


আপডেট: আমি বেশ কিছুক্ষণ আগে এর উত্তর দিয়েছি, এবং সত্যই এটি আপডেট করতে চাই। কলব্যাকগুলি একেবারে ঠিক থাকলেও, আমার অভিজ্ঞতায় তারা এমন কোডের দিকে ঝোঁক দেয় যা পড়া এবং বজায় রাখা আরও কঠিন। এমন পরিস্থিতি রয়েছে যেখানে আমি এখনও তাদের ব্যবহার করি যেমন অগ্রগতি ইভেন্টগুলিতে পাস এবং পরামিতিগুলির মতো। এই আপডেটটি কেবল বিকল্পগুলিকে জোর দেওয়ার জন্য।

এছাড়াও মূল প্রশ্ন specificallty ASYNC উল্লেখ না, তাই ক্ষেত্রে কেউ বিভ্রান্ত হয়ে গেলেই আপনার ফাংশন সমলয় হলে, এটা হবে যখন বলা অবরোধ করুন। উদাহরণ স্বরূপ:

doSomething()
// the function below will wait until doSomething completes if it is synchronous
doSomethingElse()

যদিও সূচিত হিসাবে ফাংশনটি অ্যাসিক্রোনাস হয় তবে আজ আমার সমস্ত অ্যাসিক্রোনাস কাজের সাথে আমি যেভাবে ঝুঁকতে দেখছি তা হ'ল অ্যাসিঙ্ক / প্রতীক্ষার সাথে। উদাহরণ স্বরূপ:

const secondFunction = async () => {
  const result = await firstFunction()
  // do something else here after firstFunction completes
}

আইএমও, অ্যাসিঙ্ক / প্রতীক্ষা সরাসরি আপনার প্রতিশ্রুতিগুলি (বেশিরভাগ সময়) ব্যবহার করার চেয়ে আপনার কোডকে আরও বেশি পঠনযোগ্য করে তোলে। আপনার যদি ক্যাচিং ত্রুটিগুলি পরিচালনা করতে হয় তবে এটি চেষ্টা / ধরার মাধ্যমে ব্যবহার করুন। এটি সম্পর্কে আরও এখানে পড়ুন: https://developer.mozilla.org/en-US/docs/Web/ জাভা স্ক্রিপ্ট / রেফারেন্স / স্টেটমেন্টস / কেস_ফংশন


9
@ জারকামস - বিস্তৃত করার জন্য যত্ন?
ম্যাট ওয়ে

7
কলব্যাকগুলি
অ্যাসিনক্রোনির

1
আপনি ঠিক বলেছেন যে আমার সেরা শব্দটি ব্যবহার করা উচিত ছিল না (আপডেট হওয়া), কলব্যাক্স বনাম প্রতিশ্রুতিগুলির সুবিধার বিষয়টি জটিলতার উপর নির্ভর করে।
ম্যাট ওয়ে

3
এটি অফটোপিক হয়ে ওঠে, তবে আমি ব্যক্তিগতভাবে এই দিনগুলিতে কলব্যাকগুলিকে প্রাধান্য দেওয়ার কারণ দেখছি না :-) গত 2 বছরে লিখিত আমার কোডগুলির কোনওটি মনে করতে পারছি না প্রতিশ্রুতি দিয়ে কলব্যাক সরবরাহ করা।
zerkms

3
আপনি যদি চান, আপনি এস 6 সেকেন্ডে তীর ফাংশনটি ব্যবহার করতে পারেন () {প্রথম ফাংশন ((প্রতিক্রিয়া) => so কনসোল.লগ (প্রতিক্রিয়া);}); }
জনক পুষ্পকুমারা

54

অ্যাসিঙ্ক ব্যবহার করুন / অপেক্ষা করুন:

async function firstFunction(){
  for(i=0;i<x;i++){
    // do something
  }
  return;
};

তারপরে এটি ফিরে আসার জন্য অপেক্ষা করতে আপনার অন্যান্য ফাংশনে অপেক্ষা করুন:

async function secondFunction(){
  await firstFunction();
  // now wait for firstFunction to finish...
  // do something else
};

9
আমাদের মধ্যে যারা পুরানো ব্রাউজারগুলিকে সমর্থন করে আটকে যায়, IE এসিঙ্ক / অপেক্ষার সমর্থন করে না
কাইল

এটি কি উভয় ফাংশনের বাইরে যেমন ব্যবহার করা যায় $(function() { await firstFunction(); secondFunction(); });?
লুইস্ট্রিক

1
@ লুইস্ট্রিক কেবল মনে রাখবেন awaitকেবল কোনও asyncপদ্ধতির অভ্যন্তরে ব্যবহার করা যেতে পারে । সুতরাং আপনি যদি আপনার পিতামাতাকে ফাংশন করেন তবে asyncআপনি যতটা ইচ্ছা async methodsভিতরে বা তার বাইরেও কল awaitকরতে পারেন।
ফওয়াজ

এটা কি সম্ভব awaitএকটি setTimeout?
শায়ান

1
@ শায়ান হ্যাঁ এটি হ'ল, অন্য ফাংশনে সেটটাইমআউট মোড়ুন যা সময় শেষ হওয়ার পরে একটি প্রতিশ্রুতি সমাধান করে।
ফওয়াজ

51

মনে হচ্ছে আপনি এখানে একটি গুরুত্বপূর্ণ পয়েন্টটি মিস করছেন: জাভাস্ক্রিপ্টটি একক থ্রেডযুক্ত সম্পাদন পরিবেশ environment আসুন আপনার কোডটি আবার দেখুন, নোট করুন আমি যুক্ত করেছি alert("Here"):

var isPaused = false;

function firstFunction(){
    isPaused = true;
    for(i=0;i<x;i++){
        // do something
    }
    isPaused = false;
};

function secondFunction(){
    firstFunction()

    alert("Here");

    function waitForIt(){
        if (isPaused) {
            setTimeout(function(){waitForIt()},100);
        } else {
            // go do that thing
        };
    }
};

আপনার জন্য অপেক্ষা করতে হবে না isPaused। যখন আপনি "এখানে" বিজ্ঞপ্তি দেখে নিলে, isPausedহতে হবে falseইতিমধ্যে, এবং firstFunctionফিরে হবে। এর কারণ আপনি forলুপের ভিতরে থেকে "ফলন" করতে পারবেন না ( // do something), লুপটি ব্যাহত না হতে পারে এবং প্রথমে সম্পূর্ণরূপে সম্পূর্ণ করতে হবে (আরও বিশদ: জাভাস্ক্রিপ্ট থ্রেড-হ্যান্ডলিং এবং জাতি-শর্তসমূহ) )।

এটি বলেছিল, আপনি এখনও কোড প্রবাহকে firstFunctionঅবিচ্ছিন্ন হতে পারেন এবং কলব্যাক ব্যবহার করতে পারেন বা কলারকে অবহিত করার প্রতিশ্রুতি রাখতে পারেন। আপনাকে forলুপ ছেড়ে দিতে হবে এবং এর ifপরিবর্তে এটি ( জেএসফিডাল ) সিমুলেট করতে হবে :

function firstFunction()
{
    var deferred = $.Deferred();

    var i = 0;
    var nextStep = function() {
        if (i<10) {
            // Do something
            printOutput("Step: " + i);
            i++;
            setTimeout(nextStep, 500); 
        }
        else {
            deferred.resolve(i);
        }
    }
    nextStep();
    return deferred.promise();
}

function secondFunction()
{
    var promise = firstFunction();
    promise.then(function(result) { 
        printOutput("Result: " + result);
    });
}

পার্শ্ব নোটে, জাভাস্ক্রিপ্ট ১.7 জেনারেটরেরyield অংশ হিসাবে কীওয়ার্ডটি চালু করেছে । এটি অন্যথায় সিঙ্ক্রোনাস জাভাস্ক্রিপ্ট কোড প্রবাহে ( আরও বিশদ এবং একটি উদাহরণ ) অ্যাসিঙ্ক্রোনাস গর্তগুলিকে "পাঞ্চ" করতে দেয় । তবে জেনারেটরগুলির জন্য ব্রাউজার সমর্থনটি বর্তমানে ফায়ারফক্স এবং ক্রোম, এএফআইএকে সীমাবদ্ধ।


3
তুমি আমাকে বাঁচালে. $ .ডেফার্ড () আমি যার জন্য বন্দুক করছি। ধন্যবাদ
টেমিটায়ো

@ নোসরটিও আমি এটি চেষ্টা করেছি। তবে ওয়েটফরআইটি পদ্ধতিটি মোটেই কল হয় না। আমি কি ভুল করছি?
ভিগামেজে

@ ভিগামেজ, আপনি কী চেষ্টা করেছেন তার জাস্টফিডেল বা কোডপেনের একটি লিঙ্ক সরবরাহ করতে পারেন?
নাকেরটিও

1
হ্যালো, আপনার উদ্বেগের জন্য আপনাকে ধন্যবাদ। আমি এটা কাজ পেয়েছিলাম। ধন্যবাদ..!
ভিগামেজে

18

প্রথমে একটি ফাংশনটি সম্পূর্ণ হওয়ার জন্য অপেক্ষা করার একটি দুর্দান্ত উপায় হ'ল async / প্রতীক্ষিত ফাংশন সহ প্রতিশ্রুতি ব্যবহার করা ।


  1. প্রথমত, একটি প্রতিশ্রুতি তৈরি করুন । আমার তৈরি ফাংশনটি 2-এর পরে শেষ হবে। আমি setTimeoutপরিস্থিতিটি প্রদর্শনের জন্য ব্যবহার করেছি যেখানে নির্দেশিকাগুলি কার্যকর করতে কিছুটা সময় নেয়।
  2. দ্বিতীয় ফাংশনের জন্য, আপনি async / অপেক্ষার ফাংশনটি ব্যবহার করতে পারেন যেখানে আপনি awaitনির্দেশাবলীর সাথে এগিয়ে যাওয়ার আগে প্রথম ফাংশনটি সম্পন্ন করবেন।

উদাহরণ:

    //1. Create a new function that returns a promise
    function firstFunction() {
      return new Promise((resolve, reject) => {
          let y = 0
          setTimeout(() => {
            for(i=0; i<10; i++){
               y++
            }
             console.log('loop completed')  
             resolve(y)
          }, 2000)
      })
    }
    
    //2. Create an async function
    async function secondFunction() {
        console.log('before promise call')
        //3. Await for the first function to complete
        let result = await firstFunction()
        console.log('promise resolved: ' + result)
        console.log('next step')
    }; 

    secondFunction()


বিঃদ্রঃ:

আপনি কেবল resolveএর Promiseমতো কোনও মান ছাড়াই পারে resolve()। আমার উদাহরণস্বরূপ, আমি resolvedসেই Promiseমানটির সাথে yআমি দ্বিতীয় ফাংশনে ব্যবহার করতে পারি।


ধন্যবাদ, এটি কাজ করে!
modInfo

হ্যাঁ এটি সর্বদা কাজ করবে। যদি কেউ এই ধরণের দৃশ্যের সাথে জড়িত তবে জাভাস্ক্রিপ্ট প্রতিশ্রুতি তাদের জন্য কৌশলটি করবে।
পুট্টামারিগৌডা এমএস

5

প্রতিশ্রুতিগুলির একমাত্র সমস্যাটি হ'ল আইই তাদের সমর্থন করে না। এজ করে, তবে এখানে প্রচুর পরিমাণে আইই 10 এবং 11 রয়েছে: https://developer.mozilla.org/en-US/docs/Web/JavaScript/ উল্লেখ / গ্লোবাল_অবজেক্টস / প্রমিস (নীচে সামঞ্জস্যতা)

সুতরাং, জাভাস্ক্রিপ্ট একক থ্রেডযুক্ত। আপনি যদি অ্যাসিক্রোনাস কল না করেন তবে এটি পূর্বাভাসের সাথে আচরণ করবে। মূল জাভাস্ক্রিপ্ট থ্রেড পরবর্তী কোডটি কার্যকর করার আগে একটি ক্রিয়াকলাপ সম্পূর্ণরূপে চালিত করবে, যাতে তারা কোডটিতে প্রদর্শিত হবে। সিঙ্ক্রোনাস ফাংশনগুলির জন্য আদেশের গ্যারান্টি দেওয়া তুচ্ছ - প্রতিটি ফাংশন এটি ডাকা আদেশ অনুসারে সম্পূর্ণরূপে কার্যকর হবে।

সিঙ্ক্রোনাস ফাংশনটিকে কাজের একটি পারমাণবিক ইউনিট হিসাবে ভাবেন । মূল জাভাস্ক্রিপ্ট থ্রেড এটিকে পুরোপুরি কার্যকর করবে, ক্রমে বিবৃতিগুলি কোডে প্রদর্শিত হবে।

তবে, নিম্নলিখিত পরিস্থিতিতে যেমন অ্যাসিক্রোনাস কলটি নিক্ষেপ করুন:

showLoadingDiv(); // function 1

makeAjaxCall(); // function 2 - contains async ajax call

hideLoadingDiv(); // function 3

এটি আপনি যা চান তা করে না । এটি তাত্ক্ষণিকভাবে ফাংশন 1, ফাংশন 2 এবং ফাংশন 3 সম্পাদন করে div ডিভি ফ্ল্যাশ লোড হচ্ছে এবং এটি শেষ হয়ে গেছে, যদিও এজ্যাক্স কলটি প্রায় সম্পূর্ণ নয়, যদিও makeAjaxCall()ফিরে এসেছে। কমপ্লিকেশনটি হ'ল makeAjaxCall()মূল কাজকর্মের থ্রেডের প্রতিটি স্পিনে অল্প অল্প করে উন্নত - এর কাজগুলি অংশগুলিতে পরিণত করেছে - এটি আশ্রয়জনকভাবে আচরণ করছে। তবে একই মূল থ্রেড, একটি স্পিন / রান চলাকালীন, সিঙ্ক্রোনাস অংশগুলি দ্রুত এবং পূর্বাভাসের সাথে কার্যকর করে।

সুতরাং, আমি যেভাবে এটি পরিচালনা করেছি : যেমনটি আমি বলেছিলাম যে ফাংশনটি কাজটির পারমাণবিক ইউনিট। আমি ফাংশন 1 এবং 2 এর কোডটি সংযুক্ত করেছি - অ্যাসিঞ্চ কলের আগে আমি ফাংশন 1 এর কোডটি ফাংশন 2 তে রেখেছি। আমি ফাংশন 1 থেকে মুক্তি পেয়েছি 1 অ্যাসিনক্রোনাস কল সহ সমস্ত কিছু এবং যথাযথভাবে কার্যকর হয়।

তারপরে, মূল জাভাস্ক্রিপ্ট থ্রেডের কয়েকটি স্পিনের পরে যখন অ্যাসিঙ্ক্রোনাস কলটি সম্পূর্ণ হয়, তখন এটি ফাংশন 3 কল করুন This এটি আদেশটির গ্যারান্টি দেয় । উদাহরণস্বরূপ, এজ্যাক্স সহ, অ্যানড্রিস্টেটচেঞ্জ ইভেন্ট হ্যান্ডলারকে একাধিকবার বলা হয়। এটি যখন রিপোর্ট হয়ে গেছে এটি সম্পূর্ণ হয়ে যায়, তারপরে আপনি চান চূড়ান্ত ফাংশনটি কল করুন।

আমি রাজি আছি এটি মেসিয়ার। আমি কোডটি প্রতিসম হতে পছন্দ করি, আমার একটি কাজ (বা এটির কাছে) ফাংশন করা পছন্দ হয় এবং এজাক্স কলটি কোনওভাবেই ডিসপ্লের জন্য দায়ী হওয়া (কলারের উপর নির্ভরতা তৈরি করা) পছন্দ করি না। কিন্তু, একটি সিঙ্ক্রোনাস ফাংশনে এম্বেড করা একটি অ্যাসিঙ্ক্রোনাস কল সহ, মৃত্যুদন্ড কার্যকর করার আদেশের নিশ্চয়তা দিতে আপস করতে হবে। এবং আইই 10 এর জন্য আমাকে কোড করতে হবে তাই কোনও প্রতিশ্রুতি নেই।

সংক্ষিপ্তসার : সিঙ্ক্রোনাস কলগুলির জন্য, গ্যারান্টিং অর্ডার তুচ্ছ। প্রতিটি ফাংশন সম্পূর্ণরূপে ডেকে আনে যাতে এটি ডাকা হত। অ্যাসিঙ্ক্রোনাস কল সহ একটি ক্রিয়াকলাপের জন্য, আদেশের গ্যারান্টি দেওয়ার একমাত্র উপায় হ'ল অ্যাসিঙ্ক কলটি সম্পূর্ণ হওয়ার সময় নিরীক্ষণ করা এবং সেই স্থিতিটি সনাক্ত হওয়ার পরে তৃতীয় ফাংশনটি কল করা।

জাভাস্ক্রিপ্ট থ্রেডের আলোচনার জন্য, দেখুন: https://medium.com/@francesco_rizzi/javascript-main-thread-dissected-43c85fce7e23 এবং https://developer.mozilla.org/en-US/docs/Web/JavaScript/ EventLoop

এছাড়াও, এই বিষয়ে আরও একটি অনুরূপ, উচ্চ রেটযুক্ত প্রশ্ন: আমি একের পর এক তাদের সম্পাদন করার জন্য 3 টি ফাংশন কীভাবে কল করব?


8
ডাউনওয়োটারদের কাছে, আমি এই উত্তরটির সাথে কী কী তা জানতে আগ্রহী হব।
করিমিট

খুব বেশি ফরম্যাটিং হচ্ছে? বিষয়বস্তু অনুসারে এটি আমার কাছে দুর্দান্ত মনে হয়েছে
tschoppi

0

এটি আমি নিয়ে এসেছি, যেহেতু আমাকে একটি শৃঙ্খলে বেশ কয়েকটি অপারেশন চালানো দরকার।

<button onclick="tprom('Hello Niclas')">test promise</button>

<script>
    function tprom(mess) {
        console.clear();

        var promise = new Promise(function (resolve, reject) {
            setTimeout(function () {
                resolve(mess);
            }, 2000);
        });

        var promise2 = new Promise(async function (resolve, reject) {
            await promise;
            setTimeout(function () {
                resolve(mess + ' ' + mess);
            }, 2000);
        });

        var promise3 = new Promise(async function (resolve, reject) {
            await promise2;
            setTimeout(function () {
                resolve(mess + ' ' + mess+ ' ' + mess);
            }, 2000);
        });

        promise.then(function (data) {
            console.log(data);
        });

        promise2.then(function (data) {
            console.log(data);
        });

        promise3.then(function (data) {
            console.log(data);
        });
    }

</script>

প্রদত্ত স্নিপেটের বর্ণনার জন্য দয়া করে কমপক্ষে একটি উচ্চ স্তরের মন্তব্য যুক্ত করুন। এটি আপনার কোড কীভাবে সমস্যাটিকে সম্বোধন করে তা ব্যাখ্যা করার জন্য।
শীত সারবারাস

সমস্যাটি ছিল প্রথমটির পরে দ্বিতীয় ফাংশনটি চালানো। আমি প্রথমটির পরে দ্বিতীয় ফাংশনটি কীভাবে চালিত করব এবং দ্বিতীয়টির পরে তৃতীয় ফাংশনটি কীভাবে চালাতে হবে তা আমি প্রদর্শন করি। কোন কোডটি প্রয়োজনীয় তা বোঝা সহজ করার জন্য আমি তিনটি ফাংশন করেছি।
নিক্লাস আর্নবার্গার

0

আপনার মূল মজাটি ফার্স্টফুনকে কল করবে তারপরে এটি শেষ হলে আপনার পরবর্তী মজা কল করবে।

async firstFunction() {
            const promise = new Promise((resolve, reject) => {
                for (let i = 0; i < 5; i++) {
                    // do something
                    console.log(i);
                    if (i == 4) {
                        resolve(i);
                    }
                }
            });
            const result = await promise;
        }

        second() {
            this.firstFunction().then( res => {
                // third function call do something
                console.log('Gajender here');
            });
        }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.