জাভাস্ক্রিপ্ট ES6 কেন একটি সংশোধনের পরে কার্যকর করা চালিয়ে যাওয়ার প্রতিশ্রুতি দেয়?


104

যেহেতু আমি বুঝতে পারি যে প্রতিশ্রুতি এমন কিছু যা সমাধান () বা প্রত্যাখ্যান () করতে পারে তবে আমি অবাক হয়েছিলাম যে প্রতিশ্রুতিতে কোডটি একটি সংশোধন বা প্রত্যাখ্যান হওয়ার পরে কার্যকর করা অব্যাহত থাকবে।

আমি প্রস্থান বা প্রত্যাবর্তনের অ্যাসিঙ্ক-বান্ধব সংস্করণ হিসাবে সংকল্পটিকে প্রত্যাখ্যান করেছি বা প্রত্যাখ্যান করেছি, যা তাত্ক্ষণিকভাবে সমস্ত কার্য সম্পাদন থামিয়ে দেবে।

নীচের উদাহরণটি কখনও কখনও সংশোধন করার পরে কনসোল.লগটি দেখায় কেন এর পিছনে চিন্তার কেউ ব্যাখ্যা করতে পারেন:

var call = function() {
    return new Promise(function(resolve, reject) {
        resolve();
        console.log("Doing more stuff, should not be visible after a resolve!");
    });
};

call().then(function() {
    console.log("resolved");
});

jsbin


13
যুক্তিসঙ্গত প্রশ্ন, কিন্তু তারপরে আবার, জেএস ঠিক এরপরে একটি বিবৃতি কার্যকর করে আপনি যেমনটি বলেছেন তা। resolve()কোনও জেএস নিয়ন্ত্রণ বিবৃতি নয় যা জাদুকরভাবে এর প্রভাব ফেলবে return, এটি কেবল একটি ফাংশন কল এবং হ্যাঁ, এর পরেও মৃত্যুদন্ড কার্যকর হয়।

এটি একটি ভাল প্রশ্ন এবং সমস্ত প্রতিক্রিয়াগুলি পড়ার পরেও আমি সেরা অনুশীলনগুলি সম্পর্কে নিশ্চিত নই ...
গ্যাব্রিয়েল গ্লেন

আমি মনে করি যে ভুল বোঝাবুঝি ঠিক ততই আপনি সংকল্পের মাধ্যমে শেষ করছেন (): প্রতিশ্রুতিটি সমাধান হওয়ার পরে ঠিক সমাধান করা হয়েছে () তবে অন্যের দ্বারা ইতিমধ্যে বলা হয়েছে, এর অর্থ এই নয় যে প্রতিশ্রুতি বাতিল হওয়া ফাংশনটি তার সমাপ্ত হয়েছিল দায়িত্বও, সুতরাং এটি "স্বাভাবিক" সমাপ্তির অবধি পৌঁছা অবধি চলতে থাকে।
জিউসেপ বার্টোন

উত্তর:


152

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

আপনি যদি resolve()আপনার প্রারম্ভিক ক্রিয়াকলাপটি থেকে প্রস্থান করতে চান তবে আপনাকে এটি এটিকে পূর্বে প্রদান করতে হবে return:

return new Promise(function(resolve, reject) {
    return resolve();
    console.log("Not doing more stuff after a return statement");
});

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

4
@ অ্যালনিটাক resolveনিজেই অ্যাসিক্রোনাস নয়, এটি সম্পূর্ণ সুসংগত। যদিও কঠোরভাবে ES6 এপিআই ব্যবহার করা হয়েছে এটি পর্যবেক্ষণযোগ্য নয় এটি সিঙ্ক্রোনাস বা অ্যাসিনক্রোনাস ron
ইসাইলিজা

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

@ অলনিটক: আপনি কী বলছেন তা আমি বুঝতে পেরেছি। আমি কেবল এটির ব্যাখ্যা দিয়েছিলাম কেন এটি console.logপরিবর্তে কেন প্রদর্শিত হয় না কেন এটি ক্রমে প্রদর্শিত হয়। এখনও অবধি, resolveকীভাবে এবং কীভাবে প্রতিশ্রুতি দেয় সে প্রশ্নের অপ্রাসঙ্গিক আমি কীভাবে প্রশ্নের ব্যাখ্যা করি। তবে অবশ্যই প্রতিশ্রুতির প্রসঙ্গে তা জানা এখনও জরুরী। আমি আপনার উত্তরটিকে উর্ধ্বমুখী করার কারণগুলির একটি :)
ফেলিক্স ক্লিং

9
@ বেরগী, আপনার সম্পাদনায় আপনি বলেছিলেন "রিটার্ন রেজোলিউশন ();" যা অস্বাভাবিক বলে মনে হচ্ছে নিজেকে বোঝানোর জন্য সেখানে গুরুত্বের কিছু নেই যাবার জন্য, আমাকে ডকুমেন্টেশনটি পড়তে হয়েছিল এবং দেখতে হয়েছিল যে (1) সংকল্পটি () এর পরিণতিতে কোনও কিছুই প্রত্যাবর্তন করে না এবং (2) আরম্ভের কলব্যাকের ফেরতের মান দেয় না ব্যবহার করা হবে বলে মনে হচ্ছে। "সংকল্প (); প্রত্যাবর্তন" বলা কি পরিষ্কার হবে না? এর ফলে এই ব্যাঘাত এড়ানো?
ডন হ্যাচ

19

আপনি যখন resolveকোন প্রতিশ্রুতি দেবেন তখন কলব্যাকগুলি কল করা হবে যখন স্পেসিফিকেশনটিকে এখনও অ্যাসিঙ্ক্রোনালি কল করা প্রয়োজন। এটি সিঙ্ক্রোনাস এবং অ্যাসিনক্রোনাস অ্যাকশনগুলির মিশ্রণের জন্য প্রতিশ্রুতি ব্যবহার করার সময় সামঞ্জস্যপূর্ণ আচরণ নিশ্চিত করা।

অতএব আপনি যখন কল করবেন resolveতখন কলব্যাক সারিবদ্ধ থাকে এবং resolve()কল অনুসরণ করার পরে যে কোনও কোডের সাথে তত্ক্ষণাত ফাংশন সম্পাদন অব্যাহত থাকে ।

কেবল একবার জেএস ইভেন্টের লুপটিকে ফিরে নিয়ন্ত্রণ দেওয়ার পরে কলব্যাকটি সারি থেকে সরানো এবং প্রকৃতপক্ষে অনুরোধ করা যেতে পারে।


4
কলব্যাক সারিবদ্ধভাবে A + স্পেস বা ES6 তে নথিভুক্ত করা হয়েছে?
thefourtheye 6'15

4
@ থেফোর্তে: ইভেন্টের লুপের স্পেসিফিকেশন আসলে এখন এইচটিএমএল 5 এর অংশ । ES6 নামের একটি অভ্যন্তরীণ পদ্ধতি সংজ্ঞায়িত করে EnqueueJob, যা দ্বারা প্রেরণ করা হয় .then
ফেলিক্স ক্লিং

@ থিফোর্থে: আসলে, ES6 এছাড়াও সারি সংজ্ঞায়িত করেছে বলে মনে হচ্ছে: people.mozilla.org/~jorendorff/… । আমার মনে হয় ইভেন্ট লুপটি কোনওভাবে বা অন্যভাবে সম্পর্কিত।
ফেলিক্স ক্লিং

লিঙ্কগুলির জন্য @ ফ্যালিক্সকলিং ধন্যবাদ - আমি জানতাম যে এটি কীভাবে কাজ করেছিল তবে অধ্যায় এবং শ্লোকটির উদ্ধৃতি দিতে পারিনি
অ্যালনিটাক

4
@ ফেলিক্সক্লিং এটি মাইক্রোটাস্কস / ম্যাক্রোটাস্কস, এখানে অনুমানের অংশটি রয়েছে যে "ডিফার্স" "যখন চলমান এক্সিকিউশন প্রসঙ্গ না থাকে এবং এক্সিকিউশন কনটেক্সট স্ট্যাক ফাঁকা থাকে, ECMAScript প্রয়োগটি একটি জব সারিতে প্রথম পেন্ডিংজবকে সরিয়ে দেয় এবং এতে থাকা তথ্য ব্যবহার করে এতে একটি কার্যনির্বাহী প্রসঙ্গ তৈরি করতে এবং সম্পর্কিত জব অ্যাবস্ট্রাক্ট ক্রিয়াকলাপ শুরু করে ""
বেনিয়ামিন গ্রুইনবাউম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.