কলব্যাক এবং প্রতিশ্রুতিগুলির মধ্যে আসলেই কি মৌলিক পার্থক্য রয়েছে?


94

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

কিছু সাধারণ jQueryকোড এইভাবে ডিজাইন করা হয়েছে:

$.get('userDetails', {'name': 'joe'}, function(data) {
    $('#userAge').text(data.age);
});

তবে এই ধরণের কোডটি অগোছালো এবং অত্যন্ত বাসা পেতে পারে যখন আমরা যখন আগেরটি শেষ করি তখন একের পর এক অতিরিক্ত এসিঙ্ক কল করতে চাই।

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

প্রতিশ্রুতি এবং traditionalতিহ্যগত কলব্যাক্স পদ্ধতির মধ্যে পার্থক্য হ'ল অ্যাসিঙ্ক পদ্ধতিগুলি এখন প্রতিশ্রুতিবদ্ধ অবজেক্টগুলিকে সিঙ্ক্রোনালি ফিরিয়ে দেয়, যা ক্লায়েন্ট একটি কলব্যাক সেট করে। উদাহরণস্বরূপ, AngularJS এ প্রতিশ্রুতি ব্যবহার করে অনুরূপ কোড:

$http.get('userDetails', {'name': 'joe'})
    .then(function(response) {
        $('#userAge').text(response.age);
    });

সুতরাং আমার প্রশ্নটি: আসলেই কি বাস্তব পার্থক্য রয়েছে? পার্থক্যটি নিখুঁত বাক্য গঠন বলে মনে হচ্ছে।

অন্যটি কৌশল ব্যবহারের আরও গভীর কারণ রয়েছে কি?


8
হ্যাঁ: কলব্যাকগুলি কেবল প্রথম শ্রেণির ফাংশন। প্রতিশ্রুতিগুলি হ'ল মান্ডস যা মানগুলিতে শৃঙ্খলাবদ্ধকরণের জন্য একটি সামঞ্জস্যপূর্ণ প্রক্রিয়া সরবরাহ করে এবং একটি সুবিধাজনক ইন্টারফেস সরবরাহ করার জন্য কলব্যাকের সাথে উচ্চ-অর্ডার ফাংশনগুলি ব্যবহার করে।
আমন


5
@ গ্যাनेट: দুটি প্রশ্ন / উত্তরের আপেক্ষিক মানের দিক থেকে, সদৃশ ভোটটি আইএমএইচওর চারপাশে অন্যভাবে হওয়া উচিত।
বার্ট ভ্যান ইনজেন শেহেনো

উত্তর:


110

প্রতিশ্রুতিগুলি কেবল সিনট্যাকটিক চিনি say প্রতিশ্রুতি দিয়ে আপনি যা করতে পারেন তা কলব্যাক দিয়ে করতে পারেন। আসলে, বেশিরভাগ প্রতিশ্রুতি বাস্তবায়ন যখনই আপনি চান উভয়ের মধ্যে রূপান্তর করার উপায় সরবরাহ করে।

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

তাদের সামঞ্জস্যযোগ্যতা অর্জনের প্রতিশ্রুতি দেওয়া সবচেয়ে বড় (এবং সূক্ষ্মতম) উপায়গুলি হ'ল রিটার্নের মানগুলির অভিন্ন পরিচালনা এবং ব্যতিক্রম ব্যতিক্রম unc কলব্যাক সহ, কোনও ব্যতিক্রম কীভাবে পরিচালনা করা যায় তা নির্ভর করে অনেক নেস্টেড কলব্যাকগুলির মধ্যে কোনটি এটি ছুঁড়ে ফেলেছিল এবং কলব্যাক গ্রহণকারী কোন কার্যকারিতা তার বাস্তবায়নে চেষ্টা / ধরার উপর নির্ভর করে। প্রতিশ্রুতি দিয়ে, আপনি জানেন যে একটি ব্যতিক্রম যা এক কলব্যাক ফাংশন পালাতে কট অ্যান্ড এরর হ্যান্ডলার আপনার সাথে প্রদত্ত পাস হবে .error()বা .catch()

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


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

প্রতিশ্রুতি সহ:

createViewFilePage(fileDescriptor) {
    getCurrentUser().then(function(user) {
        return isUserAuthorizedFor(user.id, VIEW_RESOURCE, fileDescriptor.id);
    }).then(function(isAuthorized) {
        if(!isAuthorized) {
            throw new Error('User not authorized to view this resource.'); // gets handled by the catch() at the end
        }
        return Promise.all([
            loadUserFile(fileDescriptor.id),
            getFileDownloadCount(fileDescriptor.id),
            getCommentsOnFile(fileDescriptor.id),
        ]);
    }).then(function(fileData) {
        var fileContents = fileData[0];
        var fileDownloads = fileData[1];
        var fileComments = fileData[2];
        fileTextAreaWidget.text = fileContents.toString();
        commentsTextAreaWidget.text = fileComments.map(function(c) { return c.toString(); }).join('\n');
        downloadCounter.value = fileDownloads;
        if(fileDownloads > 100 || fileComments.length > 10) {
            hotnessIndicator.visible = true;
        }
    }).catch(showAndLogErrorMessage);
}

কলব্যাক সহ:

createViewFilePage(fileDescriptor) {
    setupWidgets(fileContents, fileDownloads, fileComments) {
        fileTextAreaWidget.text = fileContents.toString();
        commentsTextAreaWidget.text = fileComments.map(function(c) { return c.toString(); }).join('\n');
        downloadCounter.value = fileDownloads;
        if(fileDownloads > 100 || fileComments.length > 10) {
            hotnessIndicator.visible = true;
        }
    }

    getCurrentUser(function(error, user) {
        if(error) { showAndLogErrorMessage(error); return; }
        isUserAuthorizedFor(user.id, VIEW_RESOURCE, fileDescriptor.id, function(error, isAuthorized) {
            if(error) { showAndLogErrorMessage(error); return; }
            if(!isAuthorized) {
                throw new Error('User not authorized to view this resource.'); // gets silently ignored, maybe?
            }

            var fileContents, fileDownloads, fileComments;
            loadUserFile(fileDescriptor.id, function(error, result) {
                if(error) { showAndLogErrorMessage(error); return; }
                fileContents = result;
                if(!!fileContents && !!fileDownloads && !!fileComments) {
                    setupWidgets(fileContents, fileDownloads, fileComments);
                }
            });
            getFileDownloadCount(fileDescriptor.id, function(error, result) {
                if(error) { showAndLogErrorMessage(error); return; }
                fileDownloads = result;
                if(!!fileContents && !!fileDownloads && !!fileComments) {
                    setupWidgets(fileContents, fileDownloads, fileComments);
                }
            });
            getCommentsOnFile(fileDescriptor.id, function(error, result) {
                if(error) { showAndLogErrorMessage(error); return; }
                fileComments = result;
                if(!!fileContents && !!fileDownloads && !!fileComments) {
                    setupWidgets(fileContents, fileDownloads, fileComments);
                }
            });
        });
    });
}

কলব্যাক্স সংস্করণে কোড ডুপ্লিকেশন হ্রাস করার কিছু চতুর উপায় থাকতে পারে এমনকি প্রতিশ্রুতি ছাড়াই, তবে আমি খুব ভাল প্রতিশ্রুতিযুক্ত কিছু বাস্তবায়িত করতে সিদ্ধ হওয়ার কথা ভাবতে পারি ones


1
প্রতিশ্রুতিগুলির আরেকটি বড় সুবিধা হ'ল তারা async / প্রতীক্ষা বা একটি প্রতিশৈলীর সাথে আরও "চিনিকরণ" করতে সক্ষম যা yieldএড প্রতিশ্রুতিগুলির জন্য প্রতিশ্রুতিবদ্ধ মানগুলি ফিরিয়ে দেয়। এখানে সুবিধাটি হ'ল আপনি দেশীয় নিয়ন্ত্রণ প্রবাহ কাঠামোর সাথে মিশ্রিত করার ক্ষমতা পান যা তারা কতগুলি অ্যাসিঙ্ক অপারেশন সম্পাদন করে তার মধ্যে পরিবর্তিত হতে পারে। আমি এমন একটি সংস্করণ যুক্ত করব যা এটি দেখায়।
আকজয়

9
কলব্যাক এবং প্রতিশ্রুতিগুলির মধ্যে মৌলিক পার্থক্য হ'ল নিয়ন্ত্রণের বিপরীততা। কলব্যাক সহ, আপনার এপিআই অবশ্যই কলব্যাক গ্রহণ করবে , কিন্তু প্রতিশ্রুতি সহ, আপনার এপিআই অবশ্যই একটি প্রতিশ্রুতি প্রদান করবে । এটি প্রাথমিক পার্থক্য এবং এপিআই ডিজাইনের এতে বিস্তৃত প্রভাব রয়েছে।
cwharris

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

1
@ dragan.stepanovic আপনি ঠিক বলেছেন, এবং আমি ভুল পরিভাষা ব্যবহার করেছি। পার্থক্যটি ইন্ডিয়ারেশন। একটি কলব্যাক দিয়ে, ফলাফলটি দিয়ে কী করা দরকার তা আপনার অবশ্যই জেনে রাখা উচিত। একটি প্রতিশ্রুতি দিয়ে, আপনি পরে সিদ্ধান্ত নিতে পারেন।
cwharris
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.