"কলব্যাক হেল" কী এবং কীভাবে এবং কেন আরএক্স এটি সমাধান করে?


113

যে কেউ জাভাস্ক্রিপ্ট এবং নোড.জেএস জানেন না এমন ব্যক্তির জন্য একটি "কলব্যাক হেলিক" কী তা বোঝায় এমন একটি সাধারণ উদাহরণের সাথে একটি পরিষ্কার সংজ্ঞা দিতে পারে?

কখন (কোন ধরণের সেটিংসে) "কলব্যাক হেল সমস্যা" দেখা দেয়?

কেন এটি ঘটে?

"কলব্যাক হেল" সবসময় কি অ্যাসিনক্রোনাস গণনার সাথে সম্পর্কিত?

অথবা "কলব্যাক হেল্ক" কি একক থ্রেডেড অ্যাপ্লিকেশনটিতেও ঘটতে পারে?

আমি কোরসেরায় রিঅ্যাকটিভ কোর্স নিয়েছি এবং এরিক মাইজার তার এক বক্তৃতায় বলেছিলেন যে আরএক্স "কলব্যাক হেল্ক" এর সমস্যা সমাধান করে। আমি জিজ্ঞাসা করেছি কুরসেরা ফোরামে "কলব্যাক হেল" কী তবে আমি এর স্পষ্ট উত্তর পাইনি।

একটি সহজ উদাহরণে "কলব্যাক হেল্ক" ব্যাখ্যা করার পরে, আপনি কি আর দেখাতে পারবেন যে কীভাবে আরএক্স সেই সহজ উদাহরণটিতে "কলব্যাক হেল সমস্যা" সমাধান করে?

উত্তর:


136

1) জাভাস্ক্রিপ্ট এবং নোড.জেএস জানে না এমন ব্যক্তির জন্য "কলব্যাক হেল" কী?

এই অন্যান্য প্রশ্নের জাভাস্ক্রিপ্ট কলব্যাক নরকের কয়েকটি উদাহরণ রয়েছে: কীভাবে নোড.জেএসসে অ্যাসিঙ্ক্রোনাস ফাংশনগুলির দীর্ঘ বাসা বাঁধতে হবে

জাভাস্ক্রিপ্টে সমস্যাটি হ'ল কোনও গণনা "হিমায়িত" করা এবং "এর বাকি অংশগুলি" পরেরটি (অযৌক্তিকভাবে) সম্পাদন করার একমাত্র উপায় হ'ল "বাকীটি" একটি কলব্যাকের ভিতরে রাখা।

উদাহরণস্বরূপ, বলুন যে আমি কোডটি চালাতে চাই যা দেখতে এরকম দেখাচ্ছে:

x = getData();
y = getMoreData(x);
z = getMoreData(y);
...

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

getData(function(x){
    getMoreData(x, function(y){
        getMoreData(y, function(z){ 
            ...
        });
    });
});

আমি মনে করি না যে কাউকে বোঝাতে হবে যে এই সংস্করণটি আগের সংস্করণের চেয়ে খারাপ lier :-)

২) কখন (কোন ধরণের সেটিংসে) "কলব্যাক হেল সমস্যা" দেখা দেয়?

আপনার কোডে যখন প্রচুর কলব্যাক ফাংশন থাকে! আপনার কোডগুলিতে আপনার সাথে আরও বেশি কাজ করা তাদের সাথে কাজ করা আরও শক্ত হয়ে যায় এবং যখন আপনি লুপগুলি, ট্রাই-ক্যাচ ব্লক এবং এর মতো জিনিসগুলি করার দরকার হয় তখন এটি বিশেষত খারাপ হয়।

উদাহরণস্বরূপ, যতদূর আমি জানি, জাভাস্ক্রিপ্টে সিরিয়াল অ্যাসিনক্রোনাস ফাংশনগুলি সম্পাদন করার একমাত্র উপায় যেখানে পূর্ববর্তী রিটার্নগুলির পরে চালানো হয় একটি পুনরাবৃত্ত ফাংশন ব্যবহার করে। আপনি লুপের জন্য ব্যবহার করতে পারবেন না।

// we would like to write the following
for(var i=0; i<10; i++){
    doSomething(i);
}
blah();

পরিবর্তে, আমাদের লেখা শেষ হতে পারে:

function loop(i, onDone){
    if(i >= 10){
        onDone()
    }else{
        doSomething(i, function(){
            loop(i+1, onDone);
        });
     }
}
loop(0, function(){
    blah();
});

//ugh!

এই ধরণের জিনিসটি কীভাবে করা যায় তা জিজ্ঞাসা করে স্ট্যাকওভারফ্লোতে আমরা এখানে যে কতগুলি প্রশ্নের উত্তর পাই তা কতটা বিভ্রান্তিকর তা প্রমাণ করার জন্য :)

3) কেন এটি ঘটে?

এটি ঘটে কারণ জাভাস্ক্রিপ্টে কোনও গণনা বিলম্ব করার একমাত্র উপায় যাতে এটি অ্যাসিঙ্ক্রোনাস কল রিটার্নের পরে চলে তবে বিলম্বিত কোডটি কলব্যাক ফাংশনের ভিতরে রাখা। Codeতিহ্যবাহী সিঙ্ক্রোনাস স্টাইলে লেখা কোডটি আপনি বিলম্ব করতে পারবেন না যাতে আপনি সর্বত্র নেস্টেড কলব্যাকগুলি শেষ করেন।

4) অথবা "কলব্যাক হেল্ক" কি একটি একক থ্রেডেড অ্যাপ্লিকেশনটিতেও ঘটতে পারে?

অ্যাসিঙ্ক্রোনাস প্রোগ্রামিংকে সামঞ্জস্যের সাথে কাজ করতে হয় যখন একক থ্রেড সমান্তরালতার সাথে করতে হয়। দুটি ধারণা আসলে একই জিনিস নয়।

আপনার এখনও একটি একক থ্রেড প্রসঙ্গে সমবর্তী কোড থাকতে পারে। আসলে, কলব্যাক হেলকের রানী জাভাস্ক্রিপ্ট একক থ্রেডযুক্ত।

সম্মতি এবং সমান্তরালতার মধ্যে পার্থক্য কী?

৫) আপনি কী দয়া করে এটিও দেখিয়ে দিতে পারেন যে কীভাবে আরএক্স সেই সহজ উদাহরণটিতে "কলব্যাক হেল সমস্যা" সমাধান করে।

আমি বিশেষত আরএক্স সম্পর্কে কিছু জানি না, তবে সাধারণত প্রোগ্রামিং ভাষায় অ্যাসিনক্রোনাস গণনার জন্য স্থানীয় সমর্থন যুক্ত করে এই সমস্যাটি সমাধান হয়ে যায়। বাস্তবায়নগুলি পরিবর্তিত হতে পারে এবং এর মধ্যে অন্তর্ভুক্ত থাকতে পারে: অ্যাসিঙ্ক, জেনারেটর, কর্টিনস এবং কলসিসি।

পাইথনে আমরা পূর্ববর্তী লুপ উদাহরণটি এর লাইনের সাথে কিছু সহ বাস্তবায়ন করতে পারি:

def myLoop():
    for i in range(10):
        doSomething(i)
        yield

myGen = myLoop()

এটি সম্পূর্ণ কোড নয় তবে ধারণাটি হ'ল "ফলন" লুপের জন্য আমাদের বিরতি দেয় যতক্ষণ না কেউ মাইজেন.নেক্সট () কল করে। গুরুত্বপূর্ণ বিষয়টি হ'ল আমরা লুপের জন্য লুপ ব্যবহার করে কোডটি এখনও লিখতে পারি, "অভ্যন্তরীণ" যুক্তিটি চালু না করে যেমন আমাদের সেই পুনরাবৃত্তির loopকাজ করতে হয়েছিল।


সুতরাং কলব্যাক হেল্প কেবলমাত্র একটি অ্যাসিঙ্ক সেটিংয়ে ঘটতে পারে? আমার কোডটি যদি পুরো সিক্রোনাস হয় (অর্থাত্ কোনও সম্মতি নয়) তবে আমি যদি আপনার উত্তরটি সঠিকভাবে বুঝতে পারি তবে "কলব্যাক হেল্প" ঘটতে পারে না, তা কি ঠিক?
ঝেগেদুস

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

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

1
আমার স্পষ্ট করা উচিত যে কীভাবে আরএক্স সাধারণত আরও ভাল কাজ করে। আরএক্স ঘোষণামূলক rative আপনি ঘোষণা করতে পারেন যে প্রোগ্রামটি ইভেন্টগুলিতে কীভাবে প্রতিক্রিয়া জানাবে যখন সেগুলি পরে ঘটে থাকে অন্য কোনও প্রোগ্রামের যুক্তিকে প্রভাবিত না করে। এটি আপনাকে ইভেন্ট হ্যান্ডলিং কোড থেকে প্রধান লুপ কোড পৃথক করতে দেয়। আপনি স্টেট ভেরিয়েবলগুলি ব্যবহার করার সময় অ্যাসিঙ্ক ইভেন্ট অর্ডারের মতো বিশদগুলি যেমন একটি দুঃস্বপ্ন easily আমি দেখতে পেলাম যে 3 টি জাতীয় প্রতিক্রিয়া ফিরে আসার পরে নতুন নেটওয়ার্ক অনুরোধটি সম্পাদন করার জন্য বা কোনওটি ফিরে না আসে তবে পুরো চেইনটি হ্যান্ডেল করার জন্য আরএক্স সবচেয়ে পরিষ্কার বাস্তবায়ন ছিল। তারপরে এটি নিজেই পুনরায় সেট করতে পারে এবং একই 3 ইভেন্টের জন্য অপেক্ষা করতে পারে।
কলিন্থশটস

আরও একটি সম্পর্কিত মন্তব্য: আরএক্স মূলত ধারাবাহিকতা মোনাদ, যা সিপিএসের সাথে সম্পর্কিত যদি আমার ভুল না হয় তবে এটিও ব্যাখ্যা করতে পারে কীভাবে / কেন কলব্যাক / নরকের সমস্যার জন্য ভাল।
heেগেগাস

30

কেবলমাত্র প্রশ্নের উত্তর দিন: আপনি কী দয়া করে এটিও দেখিয়ে দিতে পারবেন যে কীভাবে আরএক্স সেই সহজ উদাহরণটিতে "কলব্যাক হেল সমস্যা" সমাধান করে?

যাদুটি হ'ল flatMap। @ Hugomg এর উদাহরণের জন্য আমরা Rx এ নিম্নলিখিত কোডটি লিখতে পারি:

def getData() = Observable[X]
getData().flatMap(x -> Observable[Y])
         .flatMap(y -> Observable[Z])
         .map(z -> ...)...

এটি এমন যে আপনি কিছু সিঙ্ক্রোনাস এফপি কোড লিখছেন তবে বাস্তবে আপনি এগুলিকে অবিচ্ছিন্ন করতে পারেন Scheduler


26

আরএক্স কলব্যাক জাহান্নামকে কীভাবে সমাধান করে সে প্রশ্নের সমাধান করার জন্য :

প্রথমে আবার কলব্যাক নরকের বর্ণনা দিন।

একটি কেস কল্পনা করুন যে ব্যক্তি, গ্রহ এবং গ্যালাক্সি - তিনটি সংস্থান পেতে আমাদের অবশ্যই http করা উচিত। আমাদের উদ্দেশ্য সেই ব্যক্তি যে ছায়াপথের মধ্যে বাস করে তা সন্ধান করা First তিনটি অ্যাসিক্রোনাস অপারেশনের জন্য এটি তিনটি কলব্যাক।

getPerson(person => { 
   getPlanet(person, (planet) => {
       getGalaxy(planet, (galaxy) => {
           console.log(galaxy);
       });
   });
});

প্রতিটি কলব্যাক নেস্টেড হয়। প্রতিটি অভ্যন্তরীণ কলব্যাক তার পিতামাতার উপর নির্ভরশীল। এটি কলম্বব্যাক জাহান্নামের "পিরামিড অফ ডুম" স্টাইলের দিকে নিয়ে যায় । কোডটি> সাইন এর মতো দেখাচ্ছে।

আরএক্সজেজে এটি সমাধান করার জন্য আপনি এর মতো কিছু করতে পারেন:

getPerson()
  .map(person => getPlanet(person))
  .map(planet => getGalaxy(planet))
  .mergeAll()
  .subscribe(galaxy => console.log(galaxy));

সঙ্গে mergeMapওরফে flatMapঅপারেটর আপনি এটি আরো সংক্ষিপ্ত বানাতে পারে:

getPerson()
  .mergeMap(person => getPlanet(person))
  .mergeMap(planet => getGalaxy(planet))
  .subscribe(galaxy => console.log(galaxy));

আপনি দেখতে পাচ্ছেন, কোডটি সমতল এবং পদ্ধতি কলগুলির একটি একক চেইন রয়েছে। আমাদের কাছে "ডুমের পিরামিড" নেই।

অতএব, কলব্যাক জাহান্নাম এড়ানো হয়।

আপনি যদি ভাবছিলেন, প্রতিশ্রুতি কলব্যাক জাহান্নাম এড়ানোর অন্য উপায়, তবে প্রতিশ্রুতি উত্সাহী , পর্যবেক্ষণযোগ্যদের মতো অলস নয় এবং (সাধারণত বলছেন) আপনি এগুলি সহজে বাতিল করতে পারবেন না।


আমি জেএস বিকাশকারী নই, তবে এটি সহজ ব্যাখ্যা
ওমর বেশারি

15

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

এটি প্রায়শই ঘটে যখন আচরণের নির্ভরতা থাকে, অর্থাত্ যখন সি এর আগে বি এর আগে অবশ্যই A ঘটে থাকে তখন আপনি কোডটি পান:

a({
    parameter : someParameter,
    callback : function() {
        b({
             parameter : someOtherParameter,
             callback : function({
                 c(yetAnotherParameter)
        })
    }
});

আপনার কোডটিতে যদি এরকম আচরণগত নির্ভরতা প্রচুর থাকে তবে তা দ্রুত সমস্যা হতে পারে। বিশেষত যদি এটি শাখা ...

a({
    parameter : someParameter,
    callback : function(status) {
        if (status == states.SUCCESS) {
          b(function(status) {
              if (status == states.SUCCESS) {
                 c(function(status){
                     if (status == states.SUCCESS) {
                         // Not an exaggeration. I have seen
                         // code that looks like this regularly.
                     }
                 });
              }
          });
        } elseif (status == states.PENDING {
          ...
        }
    }
});

এটি করবে না। এই সমস্ত কলব্যাকগুলি প্রায় না পেরে আমরা কীভাবে অ্যাসিক্রোনাস কোডটি নির্ধারিত ক্রমে কার্যকর করতে পারি?

আরএক্স 'প্রতিক্রিয়াশীল এক্সটেনশানগুলির' জন্য ছোট। আমি এটি ব্যবহার করি নি, তবে গুগলিং পরামর্শ দেয় এটি একটি ইভেন্ট-ভিত্তিক কাঠামো, যা বোঝা যায়। ইভেন্টগুলি হ'ল ভঙ্গুর সংযোজন না তৈরি করে কোড কার্যকর করতে একটি সাধারণ প্যাটার্ন । আপনি সিটিকে 'বিফিনিশড' ইভেন্টটি শুনতে পারেন যা কেবলমাত্র 'এফিনিশড' শোনা বলা হয়ে যাওয়ার পরে ঘটে। তারপরে আপনি সহজেই অতিরিক্ত পদক্ষেপগুলি যুক্ত করতে বা এই ধরণের আচরণটি প্রসারিত করতে পারেন এবং কেবল আপনার পরীক্ষার ক্ষেত্রে ইভেন্টগুলি সম্প্রচার করে আপনার কোডটি কার্যকরভাবে পরীক্ষা করে দেখতে পারে।


1

কল হ্যাক মানে হ'ল আপনি অন্য কলব্যাকের অভ্যন্তরে কলব্যাকের অভ্যন্তরে রয়েছেন এবং আপনার প্রয়োজনীয়তা পূরণ না হওয়া অবধি এটি কলমে পৌঁছে যাবে।

আসুন নির্ধারিত টাইমআউট এপিআই ব্যবহার করে ভুয়া এজাক্স কলের উদাহরণের মাধ্যমে বুঝতে পারি, ধরা যাক আমাদের একটি রেসিপি এপিআই রয়েছে, আমাদের সমস্ত রেসিপি ডাউনলোড করতে হবে।

<body>
    <script>
        function getRecipe(){
            setTimeout(()=>{
                const recipeId = [83938, 73838, 7638];
                console.log(recipeId);
            }, 1500);
        }
        getRecipe();
    </script>
</body>

উপরের উদাহরণে 1.5 সেকেন্ডের পরে যখন টাইমার কল কল কোডের অভ্যন্তরে শেষ হয় তখন অন্য কথায়, আমাদের জাল এজ্যাক্স কলের মাধ্যমে সমস্ত রেসিপি সার্ভার থেকে ডাউনলোড করা হবে। এখন আমাদের একটি নির্দিষ্ট রেসিপি ডেটা ডাউনলোড করতে হবে।

<body>
    <script>
        function getRecipe(){
            setTimeout(()=>{
                const recipeId = [83938, 73838, 7638];
                console.log(recipeId);
                setTimeout(id=>{
                    const recipe = {title:'Fresh Apple Juice', publisher:'Suru'};
                    console.log(`${id}: ${recipe.title}`);
                }, 1500, recipeId[2])
            }, 1500);
        }
        getRecipe();
    </script>
</body>

একটি নির্দিষ্ট রেসিপি ডেটা ডাউনলোড করতে আমরা আমাদের প্রথম কলব্যাকের ভিতরে কোড লিখেছি এবং রেসিপি আইডিকে পাশ করেছি।

এখন আসুন আমরা আইডি 7638 এর রেসিপিটির একই প্রকাশকের সমস্ত রেসিপিগুলি ডাউনলোড করতে হবে say

<body>
    <script>
        function getRecipe(){
            setTimeout(()=>{
                const recipeId = [83938, 73838, 7638];
                console.log(recipeId);
                setTimeout(id=>{
                    const recipe = {title:'Fresh Apple Juice', publisher:'Suru'};
                    console.log(`${id}: ${recipe.title}`);
                    setTimeout(publisher=>{
                        const recipe2 = {title:'Fresh Apple Pie', publisher:'Suru'};
                        console.log(recipe2);
                    }, 1500, recipe.publisher);
                }, 1500, recipeId[2])
            }, 1500);
        }
        getRecipe();
    </script>
</body>

আমাদের প্রয়োজনগুলি পূরণ করতে যা প্রকাশক নাম সুরুর সমস্ত রেসিপি ডাউনলোড করতে হয়, আমরা আমাদের দ্বিতীয় কলটির ভিতরে কোড লিখেছিলাম। এটা পরিষ্কার যে আমরা একটি কলব্যাক চেইন লিখেছিলাম যাকে কলব্যাক হেল বলা হয়।

যদি আপনি কলব্যাক জাহান্নাম এড়াতে চান, আপনি প্রতিশ্রুতিটি ব্যবহার করতে পারেন, যা জেএস এস 6 বৈশিষ্ট্য, প্রতিটি প্রতিশ্রুতিতে একটি কলব্যাক লাগে যা কোনও প্রতিশ্রুতি পূর্ণ-পূর্ণ হলে called প্রতিশ্রুতি কলব্যাকের দুটি বিকল্প রয়েছে এটি সমাধান করা বা প্রত্যাখ্যান করা হয়। মনে করুন আপনার এপিআই কলটি সফল হয়েছে আপনি কলটি কল করতে এবং সমাধানের মাধ্যমে ডেটা পাস করতে পারেন, তারপরে () ব্যবহার করে আপনি এই ডেটা পেতে পারেন । তবে যদি আপনার এপিআই ব্যর্থ হয় আপনি প্রত্যাখ্যান করতে পারেন, ত্রুটিটি ধরতে ক্যাচ ব্যবহার করুন । একটি প্রতিশ্রুতি মনে রেখো সবসময় ব্যবহার তারপর মোকাবিলা করতে হবে এবং এর জন্য ধরা জন্য প্রত্যাখ্যান

আসুন আমরা প্রতিশ্রুতি ব্যবহার করে পূর্ববর্তী কলব্যাক হেল্প সমস্যাটি সমাধান করি।

<body>
    <script>

        const getIds = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                const downloadSuccessfull = true;
                const recipeId = [83938, 73838, 7638];
                if(downloadSuccessfull){
                    resolve(recipeId);
                }else{
                    reject('download failed 404');
                }
            }, 1500);
        });

        getIds.then(IDs=>{
            console.log(IDs);
        }).catch(error=>{
            console.log(error);
        });
    </script>
</body>

এখন নির্দিষ্ট রেসিপিটি ডাউনলোড করুন:

<body>
    <script>
        const getIds = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                const downloadSuccessfull = true;
                const recipeId = [83938, 73838, 7638];
                if(downloadSuccessfull){
                    resolve(recipeId);
                }else{
                    reject('download failed 404');
                }
            }, 1500);
        });

        const getRecipe = recID => {
            return new Promise((resolve, reject)=>{
                setTimeout(id => {
                    const downloadSuccessfull = true;
                    if (downloadSuccessfull){
                        const recipe = {title:'Fresh Apple Juice', publisher:'Suru'};
                        resolve(`${id}: ${recipe.title}`);
                    }else{
                        reject(`${id}: recipe download failed 404`);
                    }

                }, 1500, recID)
            })
        }
        getIds.then(IDs=>{
            console.log(IDs);
            return getRecipe(IDs[2]);
        }).
        then(recipe =>{
            console.log(recipe);
        })
        .catch(error=>{
            console.log(error);
        });
    </script>
</body>

এখন আমরা getRecipe এর মত allRecipeOfAPublisher কল করে আরেকটি পদ্ধতি লিখতে পারি যা প্রতিশ্রুতিও ফিরে আসবে এবং আমরা AllRecipeOfAPublisher এর সমাধানের প্রতিশ্রুতি পাওয়ার জন্য আরও একটি (তখন) লিখতে পারি, আমি আশা করি এই মুহুর্তে আপনি নিজেই এটি করতে পারবেন।

সুতরাং আমরা কীভাবে প্রতিশ্রুতিগুলি তৈরি করা এবং সেবন করতে হবে তা শিখেছি, আসুন এসইএনসি / ওয়েভেট যা এস -8 এ প্রবর্তিত হয় তা ব্যবহার করে একটি প্রতিশ্রুতি গ্রহণ করা সহজ করি।

<body>
    <script>

        const getIds = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                const downloadSuccessfull = true;
                const recipeId = [83938, 73838, 7638];
                if(downloadSuccessfull){
                    resolve(recipeId);
                }else{
                    reject('download failed 404');
                }
            }, 1500);
        });

        const getRecipe = recID => {
            return new Promise((resolve, reject)=>{
                setTimeout(id => {
                    const downloadSuccessfull = true;
                    if (downloadSuccessfull){
                        const recipe = {title:'Fresh Apple Juice', publisher:'Suru'};
                        resolve(`${id}: ${recipe.title}`);
                    }else{
                        reject(`${id}: recipe download failed 404`);
                    }

                }, 1500, recID)
            })
        }

        async function getRecipesAw(){
            const IDs = await getIds;
            console.log(IDs);
            const recipe = await getRecipe(IDs[2]);
            console.log(recipe);
        }

        getRecipesAw();
    </script>
</body>

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

  async function getRecipesAw(){
            const IDs = await getIds;
            console.log(IDs);
            const recipe = await getRecipe(IDs[2]);
            console.log(recipe);
        }

অপেক্ষারত ব্যবহার করতে আমাদের একটি অ্যাসিঙ্ক ফাংশন প্রয়োজন হবে, আমরা কোনও প্রতিশ্রুতি ফিরিয়ে দিতে পারি তাই সমাধান প্রতিশ্রুতির জন্য ব্যবহার করতে পারি এবং প্রতিশ্রুতি প্রত্যাখ্যান করার জন্য ক্যাথ

উপরের উদাহরণ থেকে:

 async function getRecipesAw(){
            const IDs = await getIds;
            const recipe = await getRecipe(IDs[2]);
            return recipe;
        }

        getRecipesAw().then(result=>{
            console.log(result);
        }).catch(error=>{
            console.log(error);
        });

0

কলব্যাক জাহান্নামকে এড়াতে পারে এমন এক উপায় হল এফআরপি ব্যবহার করা যা আরএক্সের একটি "বর্ধিত সংস্করণ"।

আমি সম্প্রতি এফআরপি ব্যবহার শুরু করেছি কারণ এটির Sodium( http://sodium.nz/ ) নামক একটি ভাল বাস্তবায়ন আমি পেয়েছি ।

একটি সাধারণ কোড এর মতো দেখায় (Scala.js):

def render: Unit => VdomElement = { _ =>
  <.div(
    <.hr,
    <.h2("Note Selector"),
    <.hr,
    <.br,
    noteSelectorTable.comp(),
    NoteCreatorWidget().createNewNoteButton.comp(),
    NoteEditorWidget(selectedNote.updates()).comp(),
    <.hr,
    <.br
  )
}

selectedNote.updates()এটি Streamযা আগুন দেয় যা selectedNode(যা একটি Cell) পরিবর্তিত হয়, NodeEditorWidgetতারপরে একইভাবে আপডেট হয়।

সুতরাং, এর সামগ্রীর উপর নির্ভর করে selectedNode Cell, বর্তমানে সম্পাদিত Noteপরিবর্তন হবে।

এই কোডটি পুরোপুরি কলব্যাকগুলি এড়িয়ে চলে, প্রায়, ক্যাকব্যাক-এসটিকে অ্যাপের "বহিরাগত স্তর" / "পৃষ্ঠ" এ ঠেলে দেওয়া হয়, যেখানে রাষ্ট্র বাহ্যিক বিশ্বের সাথে লজিক ইন্টারফেস পরিচালনা করে। অভ্যন্তরীণ রাষ্ট্র পরিচালনার যুক্তিতে (যা একটি রাষ্ট্রীয় মেশিন প্রয়োগ করে) এর মধ্যে ডেটা প্রচারের জন্য কোনও কলব্যাকের প্রয়োজন নেই।

সম্পূর্ণ উত্স কোড এখানে

নীচের সাধারণ তৈরি / প্রদর্শন / আপডেট উদাহরণের জন্য সংক্ষিপ্ত বিবরণে উপরে কোড স্নিপেট:

এখানে চিত্র বর্ণনা লিখুন

এই কোডটি সার্ভারে আপডেটও প্রেরণ করে, তাই আপডেট হওয়া সংস্থাগুলিতে পরিবর্তনগুলি স্বয়ংক্রিয়ভাবে সার্ভারে সংরক্ষণ করা হয়।

সমস্ত ইভেন্ট হ্যান্ডলিংয়ের Streamএস এবং Cellএস ব্যবহার করে যত্ন নেওয়া হয় । এগুলি এফআরপি ধারণা। কলব্যাকগুলি কেবল তখনই প্রয়োজন যেখানে বহিরাগত বিশ্বের সাথে এফআরপি যুক্তিযুক্ত ইন্টারফেস, যেমন ব্যবহারকারীর ইনপুট, পাঠ্য সম্পাদনা, বোতাম টিপানো, এজ্যাক্স কল রিটার্ন।

ডেটা ফ্লো এফআরপি (সোডিয়াম লাইব্রেরি দ্বারা বাস্তবায়িত) ব্যবহার করে একটি ঘোষণামূলক পদ্ধতিতে স্পষ্টভাবে বর্ণিত হয়, সুতরাং ডেটা প্রবাহ বর্ণনা করার জন্য কোনও ইভেন্ট হ্যান্ডলিং / কলব্যাক লজিকের প্রয়োজন হয় না।

এফআরপি (যা আরএক্সের আরও "কড়া" সংস্করণ) একটি ডেটা ফ্লো গ্রাফকে বর্ণনা করার একটি উপায় যা এতে স্টোড যুক্ত নোডগুলি ধারণ করতে পারে। ইভেন্টগুলিতে নোড ( Cellগুলি গুলি) যুক্ত রাজ্যে রাজ্যের পরিবর্তনগুলির সূত্রপাত হয় ।

সোডিয়াম একটি উচ্চতর অর্ডার এফআরপি লাইব্রেরি, যার অর্থ flatMap/ switchআদিম ব্যবহার করে ডেটা ফ্লো গ্রাফ রানটাইমে পুনরায় সাজানো যায়।

আমি সোডিয়াম বইটি খতিয়ে দেখার পরামর্শ দিয়েছি , এটি কীভাবে এফআরপি সমস্ত কলব্যাকগুলি থেকে মুক্তি পাবে যা কিছু বাহ্যিক উত্তেজনার প্রতিক্রিয়া হিসাবে অ্যাপ্লিকেশন স্টেট আপডেট করার সাথে সম্পর্কিত যা প্রবাহের যুক্তি বর্ণনা করার জন্য প্রয়োজনীয় নয় detail

এফআরপি ব্যবহার করে, কেবলমাত্র সেই কলব্যাকগুলিই রাখা দরকার যা বাহ্যিক বিশ্বের সাথে ইন্টারঅ্যাকশন বর্ণনা করে। অন্য কথায়, যখন কেউ একটি এফআরপি কাঠামো ব্যবহার করে (যেমন সোডিয়াম) বা যখন কেউ "এফআরপি মত" কাঠামো ব্যবহার করে (যেমন আরএক্স) তখন ডেটাফ্লোটি কার্যকরী / ঘোষণামূলক পদ্ধতিতে বর্ণিত হয়।

সোডিয়াম জাভাস্ক্রিপ্ট / টাইপসক্রিপ্ট জন্য উপলব্ধ।


-3

যদি আপনার কলব্যাক এবং নরকের কলব্যাক সম্পর্কে জ্ঞান না থাকে তবে সমস্যা নেই st প্রথমটি হ'ল কলটি ফিরে কল্পনা করুন hell উদাহরণস্বরূপ: হরক কল ব্যাক এমন একটি যা আমরা ক্লাসের ভিতরে একটি ক্লাস সঞ্চয় করতে পারি you যেমন আপনি শুনেছেন সি, সি ++ ল্যাঙ্গুয়েজে যে নেস্টেড রয়েছে সে সম্পর্কে ested


উত্তরটি আরও সহায়ক হবে যদি এতে 'কলব্যাক
হেল্ক

-4

Jazz.js https://github.com/Javanile/Jazz.js ব্যবহার করুন

এটি এর মতো সরল করুন:

    // সিক্যুয়ালিটি টাস্কে জড়িত
    jj.script ([
        // প্রথম কাজ
        ফাংশন (পরবর্তী) {
            // এই প্রক্রিয়া শেষে 'পরবর্তী' দ্বিতীয় কার্যের দিকে নির্দেশ করুন এবং এটি চালান 
            callAsyncProcess1 (পরবর্তী);
        },
      // দ্বিতীয় কাজ
      ফাংশন (পরবর্তী) {
        // এই প্রক্রিয়া শেষে 'পরবর্তী' পয়েন্টটি থার্ট করুন এবং এটি চালান 
        callAsyncProcess2 (পরবর্তী);
      },
      // থার্ট টাস্ক
      ফাংশন (পরবর্তী) {
        // এই প্রক্রিয়া শেষে 'পরবর্তী' নির্দেশ করুন (যদি থাকে) 
        callAsyncProcess3 (পরবর্তী);
      },
    ]);


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