প্লেইন ইংরাজিতে কলব্যাক কীভাবে ব্যাখ্যা করবেন? কলিং ফাংশন থেকে কিছু প্রসঙ্গ গ্রহণ করে তারা অন্য ফাংশন থেকে একটি ফাংশন কল করার থেকে কীভাবে আলাদা? তাদের ক্ষমতা কীভাবে একজন নবাগত প্রোগ্রামারকে ব্যাখ্যা করা যায়?
প্লেইন ইংরাজিতে কলব্যাক কীভাবে ব্যাখ্যা করবেন? কলিং ফাংশন থেকে কিছু প্রসঙ্গ গ্রহণ করে তারা অন্য ফাংশন থেকে একটি ফাংশন কল করার থেকে কীভাবে আলাদা? তাদের ক্ষমতা কীভাবে একজন নবাগত প্রোগ্রামারকে ব্যাখ্যা করা যায়?
উত্তর:
প্রায়শই কোনও অ্যাপ্লিকেশনকে তার প্রসঙ্গ / রাষ্ট্রের ভিত্তিতে বিভিন্ন ফাংশন সম্পাদন করতে হয়। এর জন্য, আমরা একটি ভেরিয়েবল ব্যবহার করি যেখানে আমরা কল করার জন্য ফাংশন সম্পর্কিত তথ্য সংরক্ষণ করব। এর প্রয়োজন অনুসারে অ্যাপ্লিকেশনটি এই ভেরিয়েবলটি ফাংশন সম্পর্কিত তথ্যের সাথে ডেকে আনবে এবং একই ভেরিয়েবলটি ব্যবহার করে ফাংশনটি কল করবে।
জাভাস্ক্রিপ্টে, উদাহরণটি নীচে রয়েছে। এখানে আমরা পদ্ধতির যুক্তিটি ভেরিয়েবল হিসাবে ব্যবহার করি যেখানে আমরা ফাংশন সম্পর্কিত তথ্য সঞ্চয় করি।
function processArray(arr, callback) {
var resultArr = new Array();
for (var i = arr.length-1; i >= 0; i--)
resultArr[i] = callback(arr[i]);
return resultArr;
}
var arr = [1, 2, 3, 4];
var arrReturned = processArray(arr, function(arg) {return arg * -1;});
// arrReturned would be [-1, -2, -3, -4]
function(arg)
মধ্যে) processArray(arr,callback)
ফাংশন
আমি এই মৃতকে সরল রাখার চেষ্টা করতে যাচ্ছি। একটি "কলব্যাক" এমন কোনও ফাংশন যা অন্য ফাংশন দ্বারা ডাকা হয় যা প্রথম ফাংশনটিকে প্যারামিটার হিসাবে গ্রহণ করে। অনেক সময়, একটি "কলব্যাক" এমন একটি ফাংশন যা কিছু ঘটলে ডাকা হয়। প্রোগ্রামার-স্পোক- এ এমন কিছুকে "ইভেন্ট" বলা যেতে পারে।
এই দৃশ্যটি কল্পনা করুন: আপনি কয়েক দিনের মধ্যে একটি প্যাকেজ আশা করছেন। প্যাকেজটি আপনার প্রতিবেশীর জন্য উপহার। অতএব, আপনি একবার প্যাকেজটি পেয়ে গেলে আপনি এটি প্রতিবেশীদের কাছে নিয়ে আসতে চান। আপনি শহরের বাইরে আছেন, এবং তাই আপনি আপনার স্ত্রীর জন্য নির্দেশনা রেখে যান।
আপনি তাদের প্যাকেজটি পেতে এবং প্রতিবেশীদের কাছে আনতে বলতে পারেন। আপনার স্ত্রী যদি কম্পিউটারের মতো নির্বোধ হন তবে তারা দরজায় বসে প্যাকেজটি না আসা পর্যন্ত অপেক্ষা করত (কোনও কিছু না করে) এবং তারপরে একবার এসে তারা এটিকে প্রতিবেশীদের হাতে তুলে দেবে। তবে এর থেকে আরও ভাল উপায় আছে। আপনার স্ত্রীকে বলুন যে তারা একবারে প্যাকেজটি গ্রহণ করে, তাদের উচিত এটি প্রতিবেশীদের মধ্যে নিয়ে আসা। তারপরে, তারা প্যাকেজটি গ্রহণ না করে সাধারণত জীবনযাপন করতে পারে।
আমাদের উদাহরণস্বরূপ, প্যাকেজ প্রাপ্তি হ'ল "ইভেন্ট" এবং প্রতিবেশীদের কাছে আনাই হ'ল "কলব্যাক"। আপনার স্ত্রী প্যাকেজটি কেবল তখনই প্যাকেজটি উপস্থিত করার জন্য আপনার নির্দেশাবলী "চালিত" করে । অনেক ভাল!
এই জাতীয় চিন্তাভাবনা দৈনন্দিন জীবনে সুস্পষ্ট, তবে কম্পিউটারগুলির মধ্যে একই ধরণের সাধারণ জ্ঞান নেই। প্রোগ্রামাররা সাধারণত কোনও ফাইলে কীভাবে লেখেন তা বিবেচনা করুন:
fileObject = open(file)
# now that we have WAITED for the file to open, we can write to it
fileObject.write("We are writing to the file.")
# now we can continue doing the other, totally unrelated things our program does
এখানে ফাইলটি খোলার আগে আমরা অপেক্ষা করি। এটি মৃত্যুদন্ডের প্রবাহকে "অবরুদ্ধ" করে এবং আমাদের প্রোগ্রাম এটি করার প্রয়োজন হতে পারে এমন অন্য কোনও কাজ করতে পারে না! পরিবর্তে আমরা যদি এটি করতে পারতাম তবে কী হবে:
# we pass writeToFile (A CALLBACK FUNCTION!) to the open function
fileObject = open(file, writeToFile)
# execution continues flowing -- we don't wait for the file to be opened
# ONCE the file is opened we write to it, but while we wait WE CAN DO OTHER THINGS!
দেখা যাচ্ছে যে আমরা কিছু ভাষা এবং ফ্রেমওয়ার্ক দিয়ে এটি করি। বেশ সুন্দর! এই ধরণের চিন্তাভাবনার সাথে কিছু বাস্তব অনুশীলন পেতে নোড.জেগুলি দেখুন ।
open
কাজ করে তা অনুমান করা যায় বলে মনে হয় । এটি কল্পনাযোগ্য যা open
ওএস তার কালো যাদু করার অপেক্ষায় থাকা অবস্থায় অভ্যন্তরীণভাবে অবরুদ্ধ হতে পারে, যার উপরে কলব্যাক কার্যকর করা হয়। এ জাতীয় ক্ষেত্রে ফলাফলের কোনও পার্থক্য নেই।
প্লেইন ইংরাজিতে কলব্যাক কীভাবে ব্যাখ্যা করবেন?
প্লেইন ইংরেজিতে, একটি কলব্যাক ফাংশন একটি মত হল ওয়ার্কার যিনি "কল ব্যাক" তার থেকে ম্যানেজার যখন তিনি একটি সম্পন্ন করেছে টাস্ক ।
কলিং ফাংশন থেকে কিছু প্রসঙ্গ গ্রহণ করে তারা অন্য ফাংশন থেকে একটি ফাংশন কল করার থেকে কীভাবে আলাদা?
এটি সত্য যে আপনি অন্য ফাংশন থেকে কোনও ফাংশন কল করছেন, তবে মূলটি হ'ল কলব্যাকটিকে কোনও অবজেক্টের মতো বিবেচনা করা হয়, তাই আপনি সিস্টেমের অবস্থার উপর ভিত্তি করে কোন ফাংশনটি কল করতে চান তা পরিবর্তন করতে পারবেন (কৌশল ডিজাইন প্যাটার্নের মতো)।
তাদের ক্ষমতা কীভাবে একজন নবাগত প্রোগ্রামারকে ব্যাখ্যা করা যায়?
কলব্যাকের শক্তি সহজেই এজেএক্স-স্টাইল ওয়েবসাইটগুলিতে দেখা যায় যা একটি সার্ভার থেকে ডেটা টানতে হবে। নতুন ডেটা ডাউনলোড করতে কিছুটা সময় লাগতে পারে। কলব্যাক ব্যতীত, আপনার সম্পূর্ণ ইউজার ইন্টারফেসটি নতুন ডেটা ডাউনলোড করার সময় "হিমশীতল" হয়ে উঠবে, বা আপনাকে কেবল পুরো পৃষ্ঠার অংশের পরিবর্তে রিফ্রেশ করতে হবে। কলব্যাকের সাহায্যে আপনি একটি "এখন লোডিং" চিত্র সন্নিবেশ করতে পারেন এবং এটি লোড হয়ে গেলে এটি নতুন ডেটাতে প্রতিস্থাপন করতে পারেন।
function grabAndFreeze() {
showNowLoading(true);
var jsondata = getData('http://yourserver.com/data/messages.json');
/* User Interface 'freezes' while getting data */
processData(jsondata);
showNowLoading(false);
do_other_stuff(); // not called until data fully downloaded
}
function processData(jsondata) { // do something with the data
var count = jsondata.results ? jsondata.results.length : 0;
$('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
$('#results_messages').html(jsondata.results || '(no new messages)');
}
এখানে jQuery এর getJSON ব্যবহার করে কলব্যাক সহ একটি উদাহরণ রয়েছে :
function processDataCB(jsondata) { // callback: update UI with results
showNowLoading(false);
var count = jsondata.results ? jsondata.results.length : 0;
$('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
$('#results_messages').html(jsondata.results || '(no new messages)');
}
function grabAndGo() { // and don't freeze
showNowLoading(true);
$('#results_messages').html(now_loading_image);
$.getJSON("http://yourserver.com/data/messages.json", processDataCB);
/* Call processDataCB when data is downloaded, no frozen User Interface! */
do_other_stuff(); // called immediately
}
প্রায়শই কলব্যাকটি state
ক ব্যবহার করে কলিং ফাংশন থেকে অ্যাক্সেস করতে হয় closure
যা কার্যকর্তার মতো তার কার্য সম্পাদন করার আগে ম্যানেজারের কাছ থেকে তথ্য নেওয়া প্রয়োজন । তৈরি করতে , আপনি ফাংশনটি ইনলাইন করতে পারেন যাতে এটি কলিং প্রসঙ্গে ডেটা দেখে:closure
/* Grab messages, chat users, etc by changing dtable. Run callback cb when done.*/
function grab(dtable, cb) {
if (null == dtable) { dtable = "messages"; }
var uiElem = "_" + dtable;
showNowLoading(true, dtable);
$('#results' + uiElem).html(now_loading_image);
$.getJSON("http://yourserver.com/user/"+dtable+".json", cb || function (jsondata) {
// Using a closure: can "see" dtable argument and uiElem variables above.
var count = jsondata.results ? jsondata.results.length : 0,
counterMsg = ['Fetched', count, 'new', dtable].join(' '),
// no new chatters/messages/etc
defaultResultsMsg = ['(no new ', dtable, ')'].join('');
showNowLoading(false, dtable);
$('#counter' + uiElem).text(counterMsg);
$('#results'+ uiElem).html(jsondata.results || defaultResultsMsg);
});
/* User Interface calls cb when data is downloaded */
do_other_stuff(); // called immediately
}
// update results_chatters when chatters.json data is downloaded:
grab("chatters");
// update results_messages when messages.json data is downloaded
grab("messages");
// call myCallback(jsondata) when "history.json" data is loaded:
grab("history", myCallback);
শেষ closure
পর্যন্ত ডগলাস ক্রকফোর্ডের একটি সংজ্ঞা এখানে দেওয়া হয়েছে :
অন্যান্য ক্রিয়াকলাপগুলির মধ্যে কার্যাদি সংজ্ঞায়িত করা যায়। অভ্যন্তরীণ ফাংশনটির বাইরের ফাংশনের vars এবং পরামিতিগুলির অ্যাক্সেস রয়েছে। যদি কোনও অভ্যন্তরীণ ফাংশনের রেফারেন্স বেঁচে থাকে (উদাহরণস্বরূপ, কলব্যাক ফাংশন হিসাবে), বাইরের ফাংশনের ভারগুলিও বেঁচে থাকে।
আরো দেখুন:
"কলব্যাক" শব্দটি দুটি বেমানান উপায়ে ব্যবহৃত হয়েছে এমন বাস্তবতার উপর চাপ দিতে ব্যর্থ হয়ে এত বুদ্ধিমান লোক দেখে আমি হতবাক হয়েছি।
দুটি উপায়ই একটি বিদ্যমান ক্রিয়ায় অতিরিক্ত কার্যকারিতা (কোনও ফাংশন সংজ্ঞা, নামবিহীন বা নামযুক্ত) পেরিয়ে একটি ফাংশনের নিজস্বকরণকে জড়িত involve অর্থাত।
customizableFunc(customFunctionality)
যদি কাস্টম কার্যকারিতাটি কেবল কোড ব্লকে প্লাগ ইন করা থাকে তবে আপনি ফাংশনটি কাস্টমাইজ করেছেন so
customizableFucn(customFunctionality) {
var data = doSomthing();
customFunctionality(data);
...
}
যদিও এই ধরণের ইনজেকশন কার্যকারিতা প্রায়শই "কলব্যাক" নামে পরিচিত, এটি সম্পর্কে তেমন কোনও তাত্পর্য নেই। খুব স্পষ্ট উদাহরণ হ'ল ফোরইচ পদ্ধতি যা কাস্টম ফাংশনটি অ্যারের প্রতিটি উপাদানকে অ্যারেতে পরিবর্তন করার জন্য প্রয়োগ করতে আর্গুমেন্ট হিসাবে সরবরাহ করা হয়।
তবে এটি এজেএক্স বা নোড.জেজে যেমন অ্যাসিঙ্ক্রোনাস প্রোগ্রামিংয়ের জন্য "কলব্যাক" ফাংশনগুলির ব্যবহার থেকে বা কেবল ব্যবহারকারী ইন্টারঅ্যাকশন ইভেন্টগুলিতে (মাউস ক্লিকগুলির মতো) কার্যকারিতা নির্ধারণের ক্ষেত্রে মূলত পৃথক । এই ক্ষেত্রে, পুরো ধারণাটি কাস্টম কার্যকারিতা সম্পাদন করার আগে একটি ঘটনামূলক ইভেন্টের জন্য অপেক্ষা করা। এটি ব্যবহারকারীর ইন্টারঅ্যাকশনের ক্ষেত্রে সুস্পষ্ট, তবে আই / ও (ইনপুট / আউটপুট) প্রক্রিয়াগুলিতেও গুরুত্বপূর্ণ যা ডিস্ক থেকে ফাইল পড়ার মতো সময় নিতে পারে। এখানেই "কলব্যাক" শব্দটি সর্বাধিক সুস্পষ্ট বোধ তৈরি করে। একবার আই / ও প্রক্রিয়া শুরু হয়ে গেলে (যেমন ডিস্ক থেকে ফাইল পড়ার জন্য জিজ্ঞাসা করা বা কোনও সার্ভারের একটি HTTP অনুরোধ থেকে ডেটা ফেরত দেওয়ার জন্য) একটি অ্যাসিনক্রোনাসপ্রোগ্রামটি শেষ হওয়ার জন্য অপেক্ষা করে না। এটি পরবর্তী যে কোনও কাজ নির্ধারিত রয়েছে তার সাথে এগিয়ে যেতে পারে এবং পঠিত ফাইল বা HTTP অনুরোধটি সম্পন্ন হয়েছে (বা এটি ব্যর্থ হয়েছে) এবং কাস্টম কার্যকারিতার জন্য ডেটা উপলব্ধ রয়েছে তা অবহিত হওয়ার পরে কেবলমাত্র কাস্টম কার্যকারিতা দিয়ে প্রতিক্রিয়া জানাতে পারে। এটি ফোনে কোনও ব্যবসায়িক কল এবং আপনার "কলব্যাক" নম্বরটি রেখে দেওয়ার মতো, যাতে কেউ যখন আপনার কাছে ফিরে আসার জন্য উপস্থিত হয় তখন তারা আপনাকে কল করতে পারে। কতক্ষণ এবং কীভাবে অন্যান্য বিষয়ে অংশ নিতে না পারার জন্য কে জানে তার জন্য এই লাইনে ঝুলানো থেকে ভাল।
অ্যাসিঙ্ক্রোনাস ব্যবহার অন্তর্নিহিতভাবে কাঙ্ক্ষিত ইভেন্টের শোনার কিছু মাধ্যমকে জড়িত করে (যেমন, i / o প্রক্রিয়া সমাপ্তি) যাতে এটি ঘটে (এবং কেবল তখনই ঘটে) কাস্টম "কলব্যাক" কার্যকারিতা কার্যকর করা হয়। সুস্পষ্ট এজেএক্স উদাহরণে, যখন সার্ভার থেকে ডেটা আসলে উপস্থিত হয়, তখন "কলব্যাক" ফাংশনটি ডিওএম সংশোধন করার জন্য সেই ডেটা ব্যবহার করতে ট্রিগার করে এবং সেই পরিমাণে ব্রাউজার উইন্ডোটিকে আবার অঙ্কিত করে।
পুনরুদ্ধার করতে। কিছু লোক "কলব্যাক" শব্দটি ব্যবহার করে যে কোনও ধরণের কাস্টম কার্যকারিতা বোঝায় যা একটি যুক্তি হিসাবে উপস্থিত ফাংশনে ইনজেকশনের হতে পারে। তবে, কমপক্ষে আমার কাছে, শব্দের সর্বাধিক উপযুক্ত ব্যবহার হ'ল ইনজেকশনের "কলব্যাক" ফাংশনটি অবিচ্ছিন্নভাবে ব্যবহৃত হয় - কেবলমাত্র এমন কোনও ঘটনার কথা প্রকাশিত হওয়ার জন্য অপেক্ষা করা হয় যা এটি অবহিত হওয়ার অপেক্ষায় রয়েছে।
Array.prototype.forEach()
এবং ফাংশনটি একটি আর্গ হিসাবে চলে গেছে setTimeout()
, এবং এগুলি বিভিন্ন প্রোগ্রামের ঘোড়া যা আপনার প্রোগ্রামটি সম্পর্কে আপনি যেভাবে যুক্তি দেখান as ।
প্রোগ্রামারবিহীন পদগুলিতে, কলব্যাক হ'ল একটি প্রোগ্রামের মধ্যে ফাঁকা স্থান।
অনেকগুলি কাগজ ফর্মের একটি সাধারণ আইটেম হ'ল "জরুরি অবস্থার ক্ষেত্রে কল করা ব্যক্তি"। সেখানে একটি ফাঁকা রেখা আছে। আপনি কারও নাম এবং ফোন নম্বর লিখুন। যদি কোনও জরুরী অবস্থা দেখা দেয় তবে সেই ব্যক্তিকে ফোন করা হয়।
এটি কী। আপনি ফর্মটি পরিবর্তন করবেন না (কোড, সাধারণত অন্য কারও)। তবে আপনি হারিয়ে যাওয়া তথ্যের টুকরো ( আপনার নম্বর) পূরণ করতে পারেন ।
উদাহরণ 1:
কলব্যাকগুলি সম্ভবত কোনও প্রোগ্রামের আচরণে যুক্ত / পরিবর্তন করার জন্য কাস্টমাইজড পদ্ধতি হিসাবে ব্যবহৃত হয়। উদাহরণস্বরূপ, কিছু সি কোড নিন যা একটি ফাংশন সম্পাদন করে, তবে কীভাবে আউটপুট প্রিন্ট করতে হয় তা জানে না। এটি যা করতে পারে তা হ'ল একটি স্ট্রিং তৈরি করা। যখন এটি স্ট্রিংটি দিয়ে কী করবেন তা নির্ধারণ করার চেষ্টা করে, এটি একটি ফাঁকা রেখা দেখায়। কিন্তু, প্রোগ্রামার আপনাকে আপনার কলব্যাকটি লিখতে ফাঁকা দিয়েছে!
এই উদাহরণস্বরূপ, আপনি কোনও পেন্সিলটি কাগজের শীটে খালি পূরণ করতে ব্যবহার করেন না, আপনি ফাংশনটি ব্যবহার করেন set_print_callback(the_callback)
।
set_print_callback
পেন্সিল হয়,the_callback
আপনার তথ্য পূরণ করা হয়।আপনি এখন প্রোগ্রামে এই ফাঁকা লাইনটি পূরণ করেছেন। যখনই এটি আউটপুট মুদ্রণের প্রয়োজন হবে, এটি সেই ফাঁকা রেখার দিকে নজর দেবে, এবং সেখানে নির্দেশাবলী অনুসরণ করবে (যেমন আপনি যে ফাংশনটি রেখেছেন তা কল করুন)) ব্যবহারিকভাবে, এটি স্ক্রিনে, লগ ফাইলটিতে, একটি প্রিন্টারে মুদ্রণের সম্ভাবনাটিকে অনুমতি দেয়, একটি নেটওয়ার্ক সংযোগ, বা এর যেকোন সংমিশ্রণের উপরে। আপনি যা করতে চান তা দিয়ে শূন্যস্থান পূরণ করেছেন।
উদাহরণ 2:
যখন আপনাকে বলা হবে যে আপনাকে জরুরী নাম্বারে কল করতে হবে, আপনি গিয়ে কাগজের ফর্মটিতে যা লেখা আছে তা পড়ুন এবং তারপরে আপনি যে নম্বরটি পড়েছেন তার কল করুন। যদি সেই লাইনটি ফাঁকা থাকে তবে কিছুই করা হবে না।
গুই প্রোগ্রামিং একইভাবে কাজ করে। যখন একটি বোতাম ক্লিক করা হয়, প্রোগ্রামটি পরবর্তী কী করা উচিত তা নির্ধারণ করতে হবে। এটি যায় এবং কলব্যাকের সন্ধান করে। এই কলব্যাকটি ফাঁকা লেবেল হিসাবে দেখা যাচ্ছে "বোতাম 1 ক্লিক করা হলে আপনি এখানে যা করেন"
আপনি যখন এটি জিজ্ঞাসা করবেন তখন বেশিরভাগ আইডিই স্বয়ংক্রিয়ভাবে আপনার জন্য শূন্যস্থান পূরণ করে (মৌলিক পদ্ধতিটি লিখুন button1_clicked
)। তবে খালি যে কোনও পদ্ধতি আপনার ভালভাবে ঝাঁকিয়ে থাকতে পারে দয়া করে । আপনি সেই কলটি কল করতে পারেন run_computations
বা butter_the_biscuits
যতক্ষণ আপনি এই কলব্যাকের নামটি যথাযথ ফাঁকে রেখেছেন। আপনি জরুরি নম্বর ফাঁকা "555-555-1212" রাখতে পারেন। এটি বেশি অর্থবোধ করে না, তবে এটি অনুমোদিত।
চূড়ান্ত দ্রষ্টব্য: আপনি কলব্যাক দিয়ে সেই ফাঁকা রেখাটি পূরণ করছেন? এটি মুছে ফেলা যায় এবং ইচ্ছায় পুনরায় লেখা যেতে পারে। (আপনার হওয়া উচিত বা না অন্য প্রশ্ন, তবে এটি তাদের শক্তির একটি অংশ)
একটি উদাহরণ দিয়ে শুরু করা সর্বদা ভাল :)
ধরে নেওয়া যাক আপনার দুটি এবং দুটি মডিউল রয়েছে বি।
আপনি চান যে মডিউল বি তে কিছু ইভেন্ট / কন্ডিশন ঘটে তখন মডিউল A কে বিজ্ঞপ্তি দেওয়া হবে তবে মডিউল বি এর আপনার মডিউল এ সম্পর্কে কোনও ধারণা নেই, এটি কেবলমাত্র একটি ফাংশন পয়েন্টারের মাধ্যমে কোনও নির্দিষ্ট ফাংশনের (মডিউল এ) একটি ঠিকানা যা এটি জানে এটি মডিউল এ দ্বারা সরবরাহ করা
সুতরাং সমস্ত বি এখনই করতে হবে, ফাংশন পয়েন্টার ব্যবহার করে যখন একটি নির্দিষ্ট ইভেন্ট / অবস্থা ঘটে তখন মডিউল এ "কলব্যাক" হয়। এ কলব্যাক ফাংশনের ভিতরে আরও প্রসেসিং করতে পারে।
*) এখানে একটি সুস্পষ্ট সুবিধা হ'ল আপনি মডিউল বি থেকে মডিউল A সম্পর্কে সমস্ত কিছু বের করে দিচ্ছেন মডিউল বি কে / কী মডিউল A সেদিকে খেয়াল রাখতে হবে না।
কল্পনা করুন যে আপনার একটি ফাংশন দরকার যা 10 স্কোয়ারের ফেরত দেয় যাতে আপনি কোনও ফাংশন লেখেন:
function tenSquared() {return 10*10;}
পরে আপনার 9 টি স্কোয়ার দরকার যাতে আপনি অন্য ফাংশনটি লিখুন:
function nineSquared() {return 9*9;}
অবশেষে আপনি এই সমস্তটি একটি জেনেরিক ফাংশন দ্বারা প্রতিস্থাপন করবেন:
function square(x) {return x*x;}
সঠিক একই চিন্তা কলব্যাকগুলির জন্য প্রযোজ্য। আপনার একটি ফাংশন রয়েছে যা কিছু করে এবং কখন ডুএ কল করে:
function computeA(){
...
doA(result);
}
পরে আপনি ঠিক একই ফাংশনটি doB কল করতে চান তার পরিবর্তে আপনি পুরো ফাংশনটি সদৃশ করতে পারেন:
function computeB(){
...
doB(result);
}
অথবা আপনি একটি পরিবর্তনশীল হিসাবে কলব্যাক ফাংশনটি পাস করতে পারেন এবং কেবল একবার ফাংশনটি থাকতে হবে:
function compute(callback){
...
callback(result);
}
তারপরে আপনাকে কেবল গণনা (ডুএ) এবং গণনা (ডওবি) কল করতে হবে।
কোড সরলকরণের বাইরে, এটি অ্যাসিঙ্ক্রোনাস কোডটি আপনাকে জানায় যে এটি সম্পূর্ণ হয়ে গেলে আপনার স্বেচ্ছাসেবী ফাংশনটি কল করে এটি সম্পন্ন হয়েছে, আপনি যখন ফোনে কাউকে কল করেন এবং কলব্যাক নম্বর ছেড়ে যান তার অনুরূপ।
জনি প্রোগ্রামারকে একজন স্ট্যাপলার দরকার, তাই তিনি অফিস সরবরাহ বিভাগে গিয়ে একজনের কাছে অনুরোধ করেন, অনুরোধ ফর্মটি পূরণ করার পরে তিনি সেখানে দাঁড়িয়ে থাকতে পারেন এবং স্টারপ্লারের জন্য গুদামের চারপাশে ক্লার্কের জন্য অপেক্ষা করতে পারেন (একটি ব্লকিং ফাংশন কলের মতো) ) বা অন্যদিকে কিছু করতে যান।
যেহেতু এটি সাধারণত সময় নেয়, জনি অনুরোধ ফর্মের সাথে একটি নোট রাখেন এবং স্টাফলার যখন পিকআপের জন্য প্রস্তুত থাকে তখন তাকে ফোন করতে বলে, তাই তিনি তার ডেস্কে ঝাঁকুনির মতো আরও কিছু করতে পারেন।
আপনি অসুস্থ বোধ করছেন তাই আপনি ডাক্তারের কাছে যান। তিনি আপনাকে পরীক্ষা করেন এবং নির্ধারণ করেন যে আপনার কিছু ওষুধের দরকার আছে। তিনি কিছু মেডস প্রেসক্রিপশন করে এবং প্রেসক্রিপশনটি আপনার স্থানীয় ফার্মাসিটিতে ডাকেন। আপনি বাড়িতে যেতে. পরে আপনার ওষুধ প্রস্তুত আপনার প্রেসক্রিপশন প্রস্তুত আছে। আপনি যান এবং এটি বাছাই।
এখানে দুটি পয়েন্ট ব্যাখ্যা করার আছে, একটি হ'ল কলব্যাক কীভাবে কাজ করে (কোনও ফাংশন ঘুরে দেখা যায় যা এর প্রসঙ্গে কোনও জ্ঞান ছাড়াই ডেকে আনা যায়), অন্যটি এর জন্য কীভাবে ব্যবহৃত হয় (ইভেন্টগুলি অবিচ্ছিন্নভাবে পরিচালনা করে)।
অন্যান্য উত্তর দ্বারা ব্যবহৃত হয়েছে যে পার্সেল আসার অপেক্ষার সাদৃশ্য উভয় ব্যাখ্যা করার জন্য একটি ভাল। একটি কম্পিউটার প্রোগ্রামে, আপনি কম্পিউটারকে একটি পার্সেল আশা করতে বলতেন। সাধারণত, এটি এখন সেখানে বসে পার্সেল না আসা পর্যন্ত অপেক্ষা করে (এবং অন্য কিছু না করে) সম্ভবত অনির্দিষ্টকালের জন্য যদি এটি কখনও না আসে। মানুষের কাছে এটি নির্বোধ শোনায়, তবে আরও ব্যবস্থা ছাড়াই কম্পিউটারে এটি সম্পূর্ণ স্বাভাবিক।
এখন কলব্যাকটি আপনার সামনের দরজার ঘণ্টা হবে। আপনি বাড়িতে কোথায় আছেন (এমনকি) বা কীভাবে বেলটি কাজ করে তা না জেনে পার্সেলটির আগমন সম্পর্কে আপনাকে অবহিত করার জন্য আপনি একটি পার্সেল পরিষেবা সরবরাহ করেন। (উদাহরণস্বরূপ, কিছু "ঘণ্টা" আসলে একটি ফোন কল প্রেরণ করে you) আপনি "কলব্যাক ফাংশন" সরবরাহ করেছেন কারণ প্রসঙ্গের বাইরে আপনি যে কোনও সময় "ডাকা" যেতে পারেন, আপনি এখন সামনের বারান্দায় বসে "হ্যান্ডেলটি" পরিচালনা করতে পারবেন ইভেন্ট "(পার্সেল আগমনের) যখনই সময় আসবে।
কল্পনা করুন যে কোনও বন্ধু আপনার বাড়ি ছেড়ে চলে যাচ্ছে, এবং আপনি তাকে বলছেন "আপনি বাড়িতে পৌঁছালে আমাকে ফোন করুন যাতে আমি জানতে পারি যে আপনি নিরাপদে এসেছেন"; এটি (আক্ষরিক) একটি কল ফিরে । কলিগব্যাক ফাংশনটি ভাষা, নির্বিশেষে এটি। কোনও কাজ শেষ হয়ে গেলে আপনি নিয়ন্ত্রণটি আপনার কাছে ফেরত দেওয়ার জন্য কিছু প্রক্রিয়া চান, যাতে আপনি আবার কল করার জন্য এটি একটি ফাংশন দেন।
পাইথনে, উদাহরণস্বরূপ,
grabDBValue( (lambda x: passValueToGUIWindow(x) ))
grabDBValue
কেবলমাত্র একটি ডাটাবেস থেকে একটি মান দখল করতে লেখা যেতে পারে এবং তারপরে আপনাকে মানটি দিয়ে কী করতে হবে তা নির্দিষ্ট করে দেওয়া যায়, সুতরাং এটি কোনও ফাংশন গ্রহণ করে। কখন বা কখন grabDBValue
ফিরে আসবে তা আপনি জানেন না, তবে / কখন হয়, আপনি কী করতে চান তা আপনি জানেন। এখানে, আমি একটি বেনামে ফাংশন (বা ল্যাম্বদা ) পাস করি যা একটি জিইউআই উইন্ডোতে মান প্রেরণ করে। আমি সহজেই এটি করে প্রোগ্রামটির আচরণটি পরিবর্তন করতে পারি:
grabDBValue( (lambda x: passToLogger(x) ))
কলব্যাকগুলি এমন ভাষাগুলিতে ভাল কাজ করে যেখানে ফাংশনগুলি প্রথম শ্রেণীর মান, যেমন সাধারণ পূর্ণসংখ্যা, চরিত্রের স্ট্রিং, বুলেটিন ইত্যাদি, সি তে, আপনি কোনও পয়েন্টারের আশেপাশে একটি ফাংশন "পাস" করতে পারেন এবং কলার এটি ব্যবহার করতে পারেন; জাভাতে, কলার নির্দিষ্ট পদ্ধতির নামের সাথে একটি নির্দিষ্ট ধরণের স্ট্যাটিক ক্লাসের জন্য জিজ্ঞাসা করবে যেহেতু শ্রেণীর বাইরে কোনও ফাংশন ("পদ্ধতি" নয়) রয়েছে; এবং বেশিরভাগ অন্যান্য গতিশীল ভাষায় আপনি কেবল সহজ বাক্য গঠন সহ একটি ফাংশন পাস করতে পারেন।
সঙ্গে ভাষায় আভিধানিক scoping (স্কীম বা পার্ল মত) আপনি ভালো একটি কৌতুক টান করতে পারেন:
my $var = 2;
my $val = someCallerBackFunction(sub callback { return $var * 3; });
# Perlistas note: I know the sub doesn't need a name, this is for illustration
$val
এই ক্ষেত্রে 6
কারণ কলব্যাকের সংজ্ঞা দেওয়া হয়েছিল এমন লেজিকাল পরিবেশে ঘোষিত চলকগুলিতে অ্যাক্সেস রয়েছে । লেক্সিকাল স্কোপ এবং বেনামে কলব্যাকগুলি একটি শক্তিশালী সংমিশ্রণ যা নবজাতক প্রোগ্রামারের জন্য আরও অধ্যয়নের নিশ্চয়তা দেয়।
আপনার চালাতে চান এমন কিছু কোড রয়েছে। সাধারণত, আপনি যখন ফোন করেন তখন আপনি চালিয়ে যাওয়ার আগে এটি শেষ হওয়ার অপেক্ষায় থাকেন (যার ফলে আপনার অ্যাপটি ধূসর হয়ে উঠতে পারে / কার্সারের জন্য কাটানোর সময় তৈরি করতে পারে)।
বিকল্প কোড হ'ল সমান্তরালভাবে এই কোডটি চালানো এবং আপনার নিজের কাজ চালিয়ে যাওয়া। তবে যদি আপনার আসল কোডটি কোডটি বলে সেটির প্রতিক্রিয়ার উপর নির্ভর করে বিভিন্ন জিনিস করার প্রয়োজন হয়? ঠিক আছে, সেক্ষেত্রে আপনি কোডটি যে কোডটি করতে পেরে কল করতে চান তার নাম / অবস্থানে পাস করতে পারেন it's এটি একটি "কল ব্যাক"।
সাধারণ কোড: তথ্যের জন্য জিজ্ঞাসা করুন -> প্রক্রিয়া সম্পর্কিত তথ্য-> প্রক্রিয়াজাতকরণের ফলাফলের সাথে ডিল করুন-> অন্যান্য কাজ করা চালিয়ে যান।
কলব্যাক সহ: তথ্যের জন্য জিজ্ঞাসা করুন -> প্রক্রিয়া সম্পর্কিত তথ্য-> অন্যান্য কাজ করা চালিয়ে যান। এবং কিছু পরবর্তী সময়ে-> প্রক্রিয়াজাতকরণের ফলাফলের সাথে ডিল করুন।
কলব্যাক ব্যতীত অন্য কেউ বিশেষ প্রোগ্রামিং রিসোর্স (থ্রেডিং এবং অন্যান্য) এর মতো না, একটি প্রোগ্রাম হুবহু নির্দেশের ক্রম যা একের পর এক ক্রমানুসারে কার্যকর করা হয় এবং এমনকি কিছু শর্ত দ্বারা নির্ধারিত এক ধরণের "গতিশীল আচরণ" দ্বারা, সমস্ত সম্ভাব্য পরিস্থিতি পূর্বে প্রোগ্রাম করা হবে ।
সুতরাং, যদি আমাদের কোনও প্রোগ্রামে সত্যিকারের গতিশীল আচরণের প্রয়োজন হয় তবে আমরা কলব্যাক ব্যবহার করতে পারি। কলব্যাকের সাহায্যে আপনি প্যারামিটার দ্বারা নির্দেশনা দিতে পারেন, একটি প্রোগ্রাম যা পূর্বের সংজ্ঞায়িত প্যারামিটার সরবরাহ করে এমন একটি অন্য প্রোগ্রাম কল করার এবং কিছু ফলাফল প্রত্যাশা করতে পারে ( এটি চুক্তি বা অপারেশন স্বাক্ষর ), সুতরাং এই ফলাফলগুলি তৃতীয় পক্ষের প্রোগ্রাম দ্বারা উত্পাদিত / প্রক্রিয়াজাত করা যায় যা ছিল না আগে জানা ছিল না।
এই কৌশলটি কম্পিউটার দ্বারা পরিচালিত কোডগুলির সমস্ত প্রোগ্রাম, ফাংশন, অবজেক্ট এবং অন্যান্য সমস্ত ইউনিটে প্রয়োগ করা বহুবর্ষবাদের ভিত্তি।
কলব্যাকের উদাহরণ হিসাবে ব্যবহৃত মানব পৃথিবীটি আপনি যখন কোনও কাজ করছেন তখন খুব ভাল ব্যাখ্যা করা হয়েছে, ধরা যাক আপনি একজন চিত্রশিল্পী ( এখানে আপনি মূল প্রোগ্রাম, সেই পেইন্টগুলি ) এবং আপনার ক্লায়েন্টকে কখনও কখনও আপনার কাজের ফলাফল অনুমোদনের জন্য জিজ্ঞাসা করে সুতরাং, তিনি সিদ্ধান্ত নেন ছবিটি ভাল কিনা ( আপনার ক্লায়েন্টটি তৃতীয় পক্ষের প্রোগ্রাম )।
উপরের উদাহরণে আপনি একজন চিত্রশিল্পী এবং ফলাফলকে অনুমোদনের কাজটি অন্যদের কাছে "প্রতিনিধি" করেছেন, চিত্রটি প্যারামিটার এবং প্রতিটি নতুন ক্লায়েন্ট (যাকে বলা হয় "ব্যাক-ফাংশন" বলে) আপনার কাজের ফলাফল পরিবর্তন করে যে সে কী চায় ছবিটি সম্পর্কে ( ক্লায়েন্টদের করা সিদ্ধান্ত হ'ল "কলব্যাক ফাংশন" থেকে প্রাপ্ত ফলাফল ) result
আমি আশা করি এই ব্যাখ্যাটি কার্যকর হতে পারে।
আসুন ভান করুন আপনি আমাকে একটি সম্ভাব্য দীর্ঘকালীন টাস্ক দেবেন: আপনি যে পাঁচটি অনন্য ব্যক্তির মুখোমুখি হয়েছিলেন তাদের নাম পান। আমি যদি খুব কম জনবহুল অঞ্চলে থাকি তবে এটি কয়েক দিন সময় নিতে পারে। আশেপাশে ছুটে চলার সময় আপনি আপনার হাতের উপরে বসে থাকতে আগ্রহী নন তাই আপনি বলবেন, "আপনি তালিকাটি পেয়ে গেলে আমার কোষে ফোন করুন এবং এটি আমার কাছে ফিরে পড়ুন Here এখানে নম্বর" "
আপনি আমাকে একটি কলব্যাক রেফারেন্স দিয়েছেন - এমন একটি ফাংশন যা আমি আরও প্রক্রিয়াজাতকরণ বন্ধ করার জন্য সম্পাদন করব।
জাভাস্ক্রিপ্টে এটি দেখতে এর মতো কিছু হতে পারে:
var lottoNumbers = [];
var callback = function(theNames) {
for (var i=0; i<theNames.length; i++) {
lottoNumbers.push(theNames[i].length);
}
};
db.executeQuery("SELECT name " +
"FROM tblEveryOneInTheWholeWorld " +
"ORDER BY proximity DESC " +
"LIMIT 5", callback);
while (lottoNumbers.length < 5) {
playGolf();
}
playLotto(lottoNumbers);
এটি সম্ভবত বিভিন্ন উপায়ে উন্নত করা যেতে পারে। উদাহরণস্বরূপ, আপনি দ্বিতীয় কলব্যাক সরবরাহ করতে পারেন: এটি যদি এক ঘন্টার বেশি সময় নেয় তবে লাল ফোনটিতে কল করুন এবং সেই ব্যক্তিকে বলুন যা উত্তর দিয়ে গেছে যে আপনি সময় শেষ করেছেন।
টেলিফোন সিস্টেমের ক্ষেত্রে কলব্যাকগুলি খুব সহজেই বর্ণিত হয়। একটি ফাংশন কলটি টেলিফোনে কাউকে কল করা, তাকে প্রশ্ন জিজ্ঞাসা করা, উত্তর পাওয়া এবং ঝুলিয়ে রাখার অনুরূপ; কলব্যাক যুক্ত করা উপমা পরিবর্তন করে যাতে তার কাছে একটি প্রশ্ন জিজ্ঞাসার পরে আপনি তাকে নিজের নাম এবং নম্বরও দিয়ে দেন যাতে সে আপনাকে উত্তর দিয়ে ফিরে আসতে পারে। - পল জাকুবিক, "সি ++ এ কলব্যাক বাস্তবায়ন"
একটি কলব্যাক একটি ফাংশন যা দ্বিতীয় ফাংশন দ্বারা ডাকা হবে। এই দ্বিতীয় ফাংশনটি কী ফাংশনটি কল করবে তা আগাম জানে না। সুতরাং কলব্যাক ফাংশনটির পরিচয় কোথাও সংরক্ষণ করা হয়, বা প্যারামিটার হিসাবে দ্বিতীয় ফাংশনে পৌঁছে দেওয়া হয়। প্রোগ্রামিং ভাষার উপর নির্ভর করে এই "পরিচয়" হ'ল কলব্যাকের ঠিকানা, বা অন্য কোনও ধরণের পয়েন্টার বা এটি ফাংশনের নাম হতে পারে। অধ্যক্ষটি হ'ল, আমরা কিছু তথ্য সঞ্চয় বা পাস করি যা নির্বিঘ্নে ফাংশনটি সনাক্ত করে।
যখন সময় আসে, দ্বিতীয় ফাংশন কলব্যাক কল করতে পারে, সেই মুহুর্তের পরিস্থিতিগুলির উপর নির্ভর করে প্যারামিটার সরবরাহ করে। এটি সম্ভাব্য কলব্যাকের একটি সেট থেকে কলব্যাক চয়ন করতে পারে। প্রোগ্রামিং ল্যাঙ্গুয়েজটিকে "পরিচয়" জেনে দ্বিতীয় ফাংশনটি কলব্যাক করার অনুমতি দেওয়ার জন্য অবশ্যই কিছু প্রকারের সিনট্যাক্স সরবরাহ করতে হবে।
এই প্রক্রিয়াটির দুর্দান্ত সম্ভাব্য ব্যবহার রয়েছে। কলব্যাকের সাহায্যে কোনও ফাংশনের ডিজাইনার কলব্যাকের যে কোনও কলই কল করে কল করে এটি কাস্টমাইজ করতে দেয়। উদাহরণস্বরূপ, একটি বাছাইকরণ ফাংশনটি প্যারামিটার হিসাবে কলব্যাক নিতে পারে এবং কোনটি প্রথমে আসে তা সিদ্ধান্ত নিতে দুটি উপাদানগুলির তুলনা করার জন্য এই কলব্যাক হতে পারে।
যাইহোক, প্রোগ্রামিং ভাষার উপর নির্ভর করে উপরের আলোচনার "ফাংশন" শব্দটির পরিবর্তে "ব্লক," "ক্লোজার," "লাম্বদা," ইত্যাদি প্রতিস্থাপন করা যেতে পারে etc.
সাধারণত আমরা ফাংশনে ভেরিয়েবল প্রেরণ করি। ধরুন আপনার একটি টাস্ক রয়েছে যেখানে আর্গুমেন্ট হিসাবে দেওয়ার আগে ভেরিয়েবলটি প্রক্রিয়া করা দরকার - আপনি কলব্যাক ব্যবহার করতে পারেন।
function1(var1, var2)
হ'ল স্বাভাবিক উপায়।
যদি আমি var2
প্রসেস হতে চাই এবং তারপরে আর্গুমেন্ট হিসাবে প্রেরণ করা চাই তবে কী হবে?
function1(var1, function2(var2))
এটি এক ধরণের কলব্যাক - যেখানে function2
কিছু কোড কার্যকর করে এবং প্রাথমিক ফাংশনে একটি পরিবর্তনীয় ফিরিয়ে দেয়।
একটি রূপক ব্যাখ্যা:
আমার একটি পার্সেল রয়েছে আমি একটি বন্ধুর কাছে পৌঁছে দিতে চাই এবং আমি জানতে চাই যে আমার বন্ধু কখন এটি গ্রহণ করবে।
তাই আমি পার্সেলটি পোস্ট অফিসে নিয়ে যাই এবং তাদের এটি সরবরাহ করতে বলি। যদি আমি জানতে চাই যে আমার বন্ধু কখন পার্সেলটি গ্রহণ করে, আমার কাছে দুটি বিকল্প রয়েছে:
(ক) পোস্ট অফিস পৌঁছে না দেওয়া পর্যন্ত আমি অপেক্ষা করতে পারি।
(খ) বিতরণ করা হলে আমি একটি ইমেল পাব।
বিকল্প (খ) একটি কলব্যাকের সাথে সাদৃশ্যপূর্ণ।
কলব্যাক শিখানোর জন্য আপনাকে প্রথমে পয়েন্টারটি শিখতে হবে। শিক্ষার্থীরা একবার কোনও পরিবর্তনকের কাছে পয়েন্টারের ধারণাটি বুঝতে পারলে কলব্যাকের ধারণাটি আরও সহজ হয়ে যায়। ধরে নিই যে আপনি সি / সি ++ ব্যবহার করছেন, এই পদক্ষেপগুলি অনুসরণ করা যেতে পারে।
আরও অনেক জিনিস থাকতে পারে। ছাত্রদের জড়িত করুন এবং তারা আবিষ্কার করবে। আশাকরি এটা সাহায্য করবে.
সাধারণ ইংরেজিতে কলব্যাক হ'ল প্রতিশ্রুতি। জো, জেন, ডেভিড এবং সামান্থ কাজ করার জন্য একটি কার্পুল ভাগ করে। জো আজ গাড়ি চালাচ্ছে। জেন, ডেভিড এবং সামান্থার কয়েকটি বিকল্প রয়েছে:
বিকল্প 1: এটি আরও একটি পোলিং উদাহরণের মতো যেখানে জেন বাইরে রয়েছে কিনা তা পরীক্ষা করে "লুপ" করে আটকে থাকবে। জেন মাঝামাঝি সময়ে আর কিছু করতে পারে না।
বিকল্প 2: এটি কলব্যাকের উদাহরণ। জেন বাইরে যাওয়ার সময় জোকে তার ডোরবেল বাজতে বলে। তিনি দরজার বেল বাজানোর জন্য তাকে একটি "ফাংশন" দেন। জোয়ের দরজা বেল কীভাবে কাজ করে বা এটি কোথায় তা জানতে হবে না, তাকে কেবল সেই ফাংশনটি কল করতে হবে অর্থাৎ তিনি যখন সেখানে আছেন তখন দরজার বেলটি বাজান।
কলব্যাকগুলি "ইভেন্ট" দ্বারা চালিত হয়। এই উদাহরণে "ইভেন্ট" জোয়ের আগমন। এজাক্সে উদাহরণস্বরূপ ইভেন্টগুলি অ্যাসিঙ্ক্রোনাস অনুরোধের "সাফল্য" বা "ব্যর্থতা" হতে পারে এবং প্রত্যেকের একই বা ভিন্ন কলব্যাক থাকতে পারে।
জাভাস্ক্রিপ্ট অ্যাপ্লিকেশন এবং কলব্যাকের ক্ষেত্রে। আমাদের "ক্লোজার" এবং অ্যাপ্লিকেশন প্রসঙ্গটিও বুঝতে হবে। "এটি" যা বোঝায় তা জাভাস্ক্রিপ্ট বিকাশকারীদের সহজেই বিভ্রান্ত করতে পারে। এই উদাহরণে প্রতিটি ব্যক্তির "রিং_থ_ডোর্ড_বেল ()" পদ্ধতি / কলব্যাকের মধ্যে এমন আরও কিছু পদ্ধতি থাকতে পারে যা প্রত্যেক ব্যক্তির সকালের রুটিন পূর্বের উপর ভিত্তি করে করা উচিত। "টেলিভিশনটি বন্ধ করুন()". আমরা "এই "টিকে" জেন "অবজেক্ট বা" ডেভিড "অবজেক্টের উল্লেখ করতে চাইব যাতে জো তাদের তুলে নেওয়ার আগে প্রত্যেককে তাদের যা যা করা দরকার তা সেটআপ করতে পারে। জো এর সাথে কলব্যাক সেট আপ করার জন্য পদ্ধতিটিকে প্যারোডি করা প্রয়োজন যাতে "এটি" সঠিক বস্তুকে বোঝায়।
আশা করি এইটি কাজ করবে!
আমি মনে করি এটি ব্যাখ্যা করা বরং একটি সহজ কাজ।
প্রথম কলব্যাকে কেবল সাধারণ ফাংশন।
এবং আরও হ'ল আমরা এই ফাংশনটিকে কল করি (আসুন এটিকে কল করুন) অন্য ফাংশনের অভ্যন্তর থেকে (আসুন একে বি বলে দিন)।
এই সম্পর্কে জাদুটি হ'ল আমি সিদ্ধান্ত নিয়েছি, কোন ফাংশনটি বাইরে থেকে বি দ্বারা কল করা উচিত B.
আমি বিআই ফাংশনটি লেখার সময় জানি না কোন কলব্যাক ফাংশনটি কল করা উচিত। আমি যখন ফাংশন কল করি তখন বিআইও এই ফাংশনটি ফাংশন এ কল করতে বলি এটাই সব।
কলব্যাক ফাংশন কী?
এই প্রথম প্রশ্নের সহজ উত্তর হ'ল কলব্যাক ফাংশন এমন একটি ফাংশন যা ফাংশন পয়েন্টারের মাধ্যমে ডাকা হয়। আপনি যদি কোনও ফাংশনের পয়েন্টার (ঠিকানা) অন্যের কাছে আর্গুমেন্ট হিসাবে পাস করেন, যখন সেই পয়েন্টারটি ফাংশনটি কল করতে ব্যবহৃত হয় যখন এটি নির্দেশ করে যে একটি কল ব্যাক হয়েছে।
কলব্যাক ফাংশনটি সনাক্ত করা শক্ত, তবে কখনও কখনও এটি খুব দরকারী। বিশেষত যখন আপনি গ্রন্থাগার ডিজাইন করেন। কলব্যাক ফাংশন হ'ল আপনার ব্যবহারকারীকে আপনাকে একটি ফাংশনের নাম দেওয়ার জন্য জিজ্ঞাসা করার মতো, এবং আপনি নির্দিষ্ট শর্তে সেই ফাংশনটি কল করবেন।
উদাহরণস্বরূপ, আপনি একটি কলব্যাক টাইমার লিখুন। এটি আপনাকে সময়কাল এবং কোন ফাংশনটি কল করতে হবে তা নির্দিষ্ট করার অনুমতি দেয় এবং সেই অনুসারে ফাংশনটি কলব্যাক হবে। "প্রতি 10 সেকেন্ডে 5 বারের জন্য মাইফানশন () চালান"
অথবা আপনি একটি ফাংশন ডিরেক্টরি তৈরি করতে পারেন, ফাংশন নামের একটি তালিকা পাস করে এবং লাইব্রেরিকে সেই অনুযায়ী কলব্যাক করতে বলতে পারেন। "কলব্যাক সাফল্য () সাফল্য পেলে কলব্যাক ব্যর্থ () ব্যর্থ হলে।"
একটি সাধারণ ফাংশন পয়েন্টার উদাহরণ তাকান
void cbfunc()
{
printf("called");
}
int main ()
{
/* function pointer */
void (*callback)(void);
/* point to your callback function */
callback=(void *)cbfunc;
/* perform callback */
callback();
return 0;
}
কলব্যাক ফাংশনে আর্গুমেন্ট কীভাবে পাস করবেন?
কলব্যাক বাস্তবায়নের জন্য ফাংশন পয়েন্টারটি অকার্যকর * লাগে যা এটি নির্দেশ করে যে এটি কাঠামো সহ যে কোনও ধরণের ভেরিয়েবল গ্রহণ করতে পারে indicates অতএব আপনি কাঠামো দ্বারা একাধিক আর্গুমেন্ট পাস করতে পারেন।
typedef struct myst
{
int a;
char b[10];
}myst;
void cbfunc(myst *mt)
{
fprintf(stdout,"called %d %s.",mt->a,mt->b);
}
int main()
{
/* func pointer */
void (*callback)(void *); //param
myst m;
m.a=10;
strcpy(m.b,"123");
callback = (void*)cbfunc; /* point to callback function */
callback(&m); /* perform callback and pass in the param */
return 0;
}
কলব্যাক এমন একটি পদ্ধতি যা শর্ত পূরণের সময় নির্বাহের সময় নির্ধারিত হয়।
একটি "বাস্তব বিশ্বের" উদাহরণ একটি স্থানীয় ভিডিও গেম স্টোর। আপনি হাফ-লাইফ ৩ এর অপেক্ষায় রয়েছেন প্রতিদিন এটি দোকানে রয়েছে কিনা তা দেখার পরিবর্তে, আপনি গেমটি উপলভ্য হলে বিজ্ঞপ্তি দেওয়ার জন্য একটি তালিকাতে আপনার ইমেলটি নিবন্ধভুক্ত করেন। ইমেলটি আপনার "কলব্যাক" হয়ে যায় এবং শর্তটি পূরণ করার শর্তটি হ'ল গেমের উপলভ্যতা।
একটি "প্রোগ্রামারস" উদাহরণটি এমন একটি ওয়েব পৃষ্ঠা যেখানে বোতামটি ক্লিক করা হলে আপনি কোনও ক্রিয়া সম্পাদন করতে চান। আপনি একটি বোতামের জন্য একটি কলব্যাক পদ্ধতি নিবন্ধভুক্ত করুন এবং অন্যান্য কাজগুলি চালিয়ে যান। ব্যবহারকারী / বাটনে ক্লিক করলে, ব্রাউজারটি সেই ইভেন্টের কলব্যাকের তালিকাটি দেখবে এবং আপনার পদ্ধতিটি কল করবে।
কলব্যাক হ'ল অনুষ্ঠানগুলিকে সংযোজনীয়ভাবে পরিচালনা করার একটি উপায়। কলব্যাক কখন কার্যকর হবে বা কখনই তা কার্যকর করা হবে তা আপনি কখনই জানতে পারবেন না। সুবিধাটি হ'ল এটি জবাবের জন্য অপেক্ষা করার সময় আপনার প্রোগ্রাম এবং সিপিইউ চক্রকে অন্যান্য কাজ সম্পাদন করতে মুক্ত করে।
সরল এবং সরল: কলব্যাক হ'ল একটি ফাংশন যা আপনি অন্য কোনও ফাংশনকে দেন, যাতে এটি কল করতে পারে।
সাধারণত কিছু অপারেশন সম্পন্ন হলে এটি বলা হয়। যেহেতু আপনি কলটিব্যাকটি অন্য ফাংশনে দেওয়ার আগে তৈরি করেছেন, আপনি কল সাইট থেকে প্রসঙ্গ তথ্য দিয়ে এটিকে আরম্ভ করতে পারেন। এজন্য এর নামকরণ করা হয়েছে * পিছনে * - প্রথম ফাংশনটি কল করা হয়েছে সেই প্রসঙ্গে ফিরে আসে।
“কম্পিউটার প্রোগ্রামিংয়ে, কলব্যাক হল এক্সিকিউটেবল কোড, বা এক্সিকিউটেবল কোডের একটি অংশ, যা অন্য কোডে যুক্তি হিসাবে পাস হয়। এটি একটি নিম্ন-স্তরের সফ্টওয়্যার স্তরকে উচ্চ স্তরের স্তরে সংজ্ঞায়িত সাবরুটিন (বা ফাংশন) কল করতে অনুমতি দেয় ”" - উইকিপিডিয়া
ফাংশন পয়েন্টার ব্যবহার করে সি তে কলব্যাক
সি তে, ফাংশন পয়েন্টার ব্যবহার করে কলব্যাক প্রয়োগ করা হয়। ফাংশন পয়েন্টার - নাম হিসাবে বোঝা যায় একটি ফাংশনের পয়েন্টার।
উদাহরণস্বরূপ, int (* ptrFunc) ();
এখানে, ptrFunc একটি ফাংশনটির জন্য একটি পয়েন্টার যা কোনও আর্গুমেন্ট নেয় না এবং পূর্ণসংখ্যা ফেরত দেয়। প্রথম বন্ধনী রাখতে ভুলবেন না, অন্যথায় সংকলকটি ধরে নেবে যে ptrFunc একটি সাধারণ ফাংশন নাম, যা কিছুই নেয় না এবং একটি পূর্ণসংখ্যায় একটি পয়েন্টার দেয়।
ফাংশন পয়েন্টারটি প্রদর্শনের জন্য এখানে কিছু কোড রয়েছে।
#include<stdio.h>
int func(int, int);
int main(void)
{
int result1,result2;
/* declaring a pointer to a function which takes
two int arguments and returns an integer as result */
int (*ptrFunc)(int,int);
/* assigning ptrFunc to func's address */
ptrFunc=func;
/* calling func() through explicit dereference */
result1 = (*ptrFunc)(10,20);
/* calling func() through implicit dereference */
result2 = ptrFunc(10,20);
printf("result1 = %d result2 = %d\n",result1,result2);
return 0;
}
int func(int x, int y)
{
return x+y;
}
এখন আসুন ফাংশন পয়েন্টার ব্যবহার করে সি-তে কলব্যাকের ধারণাটি বোঝার চেষ্টা করি।
সম্পূর্ণ প্রোগ্রামটিতে তিনটি ফাইল রয়েছে: কলব্যাক.সি., রেজি_ক্যালব্যাক.হ এবং Reg_callback.c।
/* callback.c */
#include<stdio.h>
#include"reg_callback.h"
/* callback function definition goes here */
void my_callback(void)
{
printf("inside my_callback\n");
}
int main(void)
{
/* initialize function pointer to
my_callback */
callback ptr_my_callback=my_callback;
printf("This is a program demonstrating function callback\n");
/* register our callback function */
register_callback(ptr_my_callback);
printf("back inside main program\n");
return 0;
}
/* reg_callback.h */
typedef void (*callback)(void);
void register_callback(callback ptr_reg_callback);
/* reg_callback.c */
#include<stdio.h>
#include"reg_callback.h"
/* registration goes here */
void register_callback(callback ptr_reg_callback)
{
printf("inside register_callback\n");
/* calling our callback function my_callback */
(*ptr_reg_callback)();
}
আমরা যদি এই প্রোগ্রামটি চালাই তবে আউটপুট হবে
এটি মূল প্রোগ্রামের ভিতরে আমার_ক্যালব্যাকের অভ্যন্তরে রেজিস্টার_ক্যালব্যাকের ভিতরে ফাংশন কলব্যাক প্রদর্শনকারী একটি প্রোগ্রাম
উচ্চতর স্তর ফাংশনটি একটি সাধারণ কল হিসাবে নিম্ন স্তরের ফাংশনটিকে কল করে এবং কলব্যাক প্রক্রিয়াটি নিম্ন স্তরের ফাংশনটিকে একটি পয়েন্টারের মাধ্যমে কলব্যাক ফাংশনে কল করতে উচ্চতর স্তর ফাংশনটিকে কল করতে দেয়।
জাভাতে ইন্টারফেস ব্যবহার করে কলব্যাক
জাভাতে ফাংশন পয়েন্টারটির ধারণা নেই এটি এটি তার ইন্টারফেস প্রক্রিয়াটির মাধ্যমে কলব্যাক প্রক্রিয়া প্রয়োগ করে এখানে কোনও ফাংশন পয়েন্টারের পরিবর্তে, আমরা একটি ইন্টারফেসের এমন একটি পদ্ধতি ঘোষণা করি যা কলি তার কাজ শেষ করার পরে ডাকা হবে called
আমি এটি একটি উদাহরণের মাধ্যমে প্রদর্শন করতে পারি:
কলব্যাক ইন্টারফেস
public interface Callback
{
public void notify(Result result);
}
কলার বা উচ্চ স্তরের শ্রেণি
public Class Caller implements Callback
{
Callee ce = new Callee(this); //pass self to the callee
//Other functionality
//Call the Asynctask
ce.doAsynctask();
public void notify(Result result){
//Got the result after the callee has finished the task
//Can do whatever i want with the result
}
}
Callee বা নিম্ন স্তর ফাংশন
public Class Callee {
Callback cb;
Callee(Callback cb){
this.cb = cb;
}
doAsynctask(){
//do the long running task
//get the result
cb.notify(result);//after the task is completed, notify the caller
}
}
ইভেন্টলিস্টনার প্যাটার্ন ব্যবহার করে কলব্যাক
এই প্যাটার্নটি 0 থেকে n পর্যবেক্ষক / শ্রোতার একটি নির্দিষ্ট কাজ শেষ হয়ে গেছে বলে অবহিত করার জন্য ব্যবহৃত হয়
কলব্যাক মেকানিজম এবং ইভেন্টলাইজনার / পর্যবেক্ষক ব্যবস্থার মধ্যে পার্থক্য হ'ল কলব্যাকের ক্ষেত্রে, কলি একক কলারকে অবহিত করে, যেখানে ইভেন্টলাইজার / পর্যবেক্ষক, কলি সেই ইভেন্টে আগ্রহী যে কাউকে অবহিত করতে পারে (বিজ্ঞপ্তিটি অন্য কোনও অংশে যেতে পারে) অ্যাপ্লিকেশন যা কাজটি ট্রিগার করে না)
আমি এটি একটি উদাহরণের মাধ্যমে ব্যাখ্যা করি।
ইভেন্ট ইন্টারফেস
public interface Events {
public void clickEvent();
public void longClickEvent();
}
ক্লাস উইজেট
package com.som_itsolutions.training.java.exampleeventlistener;
import java.util.ArrayList;
import java.util.Iterator;
public class Widget implements Events{
ArrayList<OnClickEventListener> mClickEventListener = new ArrayList<OnClickEventListener>();
ArrayList<OnLongClickEventListener> mLongClickEventListener = new ArrayList<OnLongClickEventListener>();
@Override
public void clickEvent() {
// TODO Auto-generated method stub
Iterator<OnClickEventListener> it = mClickEventListener.iterator();
while(it.hasNext()){
OnClickEventListener li = it.next();
li.onClick(this);
}
}
@Override
public void longClickEvent() {
// TODO Auto-generated method stub
Iterator<OnLongClickEventListener> it = mLongClickEventListener.iterator();
while(it.hasNext()){
OnLongClickEventListener li = it.next();
li.onLongClick(this);
}
}
public interface OnClickEventListener
{
public void onClick (Widget source);
}
public interface OnLongClickEventListener
{
public void onLongClick (Widget source);
}
public void setOnClickEventListner(OnClickEventListener li){
mClickEventListener.add(li);
}
public void setOnLongClickEventListner(OnLongClickEventListener li){
mLongClickEventListener.add(li);
}
}
ক্লাস বাটন
public class Button extends Widget{
private String mButtonText;
public Button (){
}
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}
ক্লাস চেকবক্স
public class CheckBox extends Widget{
private boolean checked;
public CheckBox() {
checked = false;
}
public boolean isChecked(){
return (checked == true);
}
public void setCheck(boolean checked){
this.checked = checked;
}
}
ক্রিয়াকলাপ ক্লাস
প্যাকেজ com.som_itsolutions.training.java.exampleeventlistener;
public class Activity implements Widget.OnClickEventListener
{
public Button mButton;
public CheckBox mCheckBox;
private static Activity mActivityHandler;
public static Activity getActivityHandle(){
return mActivityHandler;
}
public Activity ()
{
mActivityHandler = this;
mButton = new Button();
mButton.setOnClickEventListner(this);
mCheckBox = new CheckBox();
mCheckBox.setOnClickEventListner(this);
}
public void onClick (Widget source)
{
if(source == mButton){
mButton.setButtonText("Thank you for clicking me...");
System.out.println(((Button) mButton).getButtonText());
}
if(source == mCheckBox){
if(mCheckBox.isChecked()==false){
mCheckBox.setCheck(true);
System.out.println("The checkbox is checked...");
}
else{
mCheckBox.setCheck(false);
System.out.println("The checkbox is not checked...");
}
}
}
public void doSomeWork(Widget source){
source.clickEvent();
}
}
অন্যান্য ক্লাস
public class OtherClass implements Widget.OnClickEventListener{
Button mButton;
public OtherClass(){
mButton = Activity.getActivityHandle().mButton;
mButton.setOnClickEventListner(this);//interested in the click event //of the button
}
@Override
public void onClick(Widget source) {
if(source == mButton){
System.out.println("Other Class has also received the event notification...");
}
}
মেইন ক্লাস
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Activity a = new Activity();
OtherClass o = new OtherClass();
a.doSomeWork(a.mButton);
a.doSomeWork(a.mCheckBox);
}
}
উপরের কোড থেকে আপনি দেখতে পাচ্ছেন যে, আমাদের একটি ইভেন্ট বলে একটি ইন্টারফেস রয়েছে যা মূলত আমাদের অ্যাপ্লিকেশনটির জন্য ঘটতে পারে এমন সমস্ত ইভেন্টের তালিকা করে। উইজেট শ্রেণি বাটন, চেকবাক্সের মতো সমস্ত ইউআই উপাদানগুলির জন্য বেস শ্রেণি। এই ইউআই উপাদানগুলি হ'ল অবজেক্টগুলি যা ফ্রেমওয়ার্ক কোড থেকে প্রকৃতপক্ষে ইভেন্টগুলি গ্রহণ করে। উইজেট শ্রেণি ইভেন্টস ইন্টারফেস প্রয়োগ করে এবং এটিতে দুটি ক্লিক করা ইন্টারফেস রয়েছে যেমন অনক্লিকএভেন্টলিস্টনার এবং অনলং ক্লিকএভেন্টলিস্টনার
এই দুটি ইন্টারফেস বাটন বা চেকবাক্সের মতো উইজেট প্রাপ্ত ইউআই উপাদান যেমন ঘটতে পারে তা শোনার জন্য দায়ী। সুতরাং আমরা যদি জাভা ইন্টারফেস ব্যবহার করে পূর্ববর্তী কলব্যাক উদাহরণের সাথে এই উদাহরণটি তুলনা করি তবে এই দুটি ইন্টারফেস কলব্যাক ইন্টারফেস হিসাবে কাজ করে। সুতরাং উচ্চ স্তরের কোড (এখানে ক্রিয়াকলাপ) এই দুটি ইন্টারফেস প্রয়োগ করে। এবং যখনই কোনও উইজেটের সাথে কোনও ইভেন্ট ঘটে তখন উচ্চ স্তরের কোড (বা উচ্চতর স্তরের কোডে প্রয়োগ করা এই ইন্টারফেসগুলির পদ্ধতি, যা এখানে ক্রিয়াকলাপ) বলা হবে।
এখন আমি কলব্যাক এবং ইভেন্টলিস্টার ধাঁচের মধ্যে মূল পার্থক্যটি আলোচনা করব। যেমনটি আমরা উল্লেখ করেছি যে কলব্যাক ব্যবহার করে, কলি কেবলমাত্র একটিমাত্র কলারকে অবহিত করতে পারে। তবে ইভেন্টলিস্টনার প্যাটার্নের ক্ষেত্রে, অ্যাপ্লিকেশনটির অন্য কোনও অংশ বা শ্রেণি বাটন বা চেকবক্সে ঘটতে পারে এমন ইভেন্টের জন্য নিবন্ধন করতে পারে। এই ধরণের শ্রেণির উদাহরণ হ'ল অন্যান্যক্লাস। আপনি যদি অন্যান্য ক্লাসের কোডটি দেখতে পান তবে আপনি দেখতে পাবেন যে এটি ক্রিয়াকলাপে সংজ্ঞায়িত বোতামে প্রদর্শিত হতে পারে ক্লিকইভেন্টের শ্রোতা হিসাবে নিজেকে নিবন্ধিত করেছে। মজার অংশটি হ'ল, ক্রিয়াকলাপ (কলার) ছাড়াও, বাটনটিতে ক্লিক ইভেন্ট যখনই ঘটে তখন এই অন্যান্য ক্লাসটিও অবহিত করা হবে।
কলব্যাকস আপনাকে অন্য সময় সম্পাদন করার জন্য কোডের অন্য একটি ব্লকে নিজের কোড সন্নিবেশ করতে দেয়, যা আপনার প্রয়োজন অনুসারে সেই কোডের অন্য ব্লকের আচরণকে সংশোধন করে বা যুক্ত করে। আরও রক্ষণাবেক্ষণযোগ্য কোড রাখতে সক্ষম হয়ে আপনি নমনীয়তা এবং অনুকূলিতকরণ অর্জন করেন।
কম হার্ডকোড = বজায় রাখা এবং পরিবর্তন করা সহজ = কম সময় = আরও ব্যবসায়ের মান = দুর্দান্ত।
উদাহরণস্বরূপ, জাভাস্ক্রিপ্টে, অ্যান্ডস্কোর.জেএস ব্যবহার করে, আপনি এই জাতীয় অ্যারেতে সমস্ত উপাদানও খুঁজে পেতে পারেন:
var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [2, 4, 6]
উদাহরণস্বরূপ অ্যান্ডস্কোর.জেএস এর সৌজন্যে: http://docamentcloud.github.com/:30core/# ফিল্টার
[সম্পাদনা] আমরা দুটি ফাংশন আছে বলে functionA এবং functionB , যদি functionA উপর নির্ভর করে functionB ।
তারপরে আমরা ফাংশনবিকে কলব্যাক ফাংশন হিসাবে কল করি Spring এটি স্প্রিং ফ্রেমওয়ার্কে বহুল ব্যবহৃত হয়।
কোনও সহকর্মীকে কোনও কাজ দেওয়া হিসাবে একটি পদ্ধতি ভাবেন। একটি সাধারণ কাজ নিম্নলিখিত হতে পারে:
Solve these equations:
x + 2 = y
2 * x = 3 * y
আপনার সহকর্মী অধ্যবসায় গণিত করে এবং আপনাকে নিম্নলিখিত ফলাফল দেয়:
x = -6
y = -4
তবে আপনার সহকর্মীর একটি সমস্যা আছে, তিনি সর্বদা স্বরলিপিগুলি বুঝতে পারেন না ^
, তবে তিনি তাদের বিবরণ দিয়ে সেগুলি বুঝতে পারেন। যেমন exponent
। প্রতিবার তিনি এর মধ্যে একটি খুঁজে পান আপনি নিম্নলিখিতটি ফিরে পান:
I don't understand "^"
চরিত্রটি আপনার সহকর্মীর কাছে কী বোঝায় তা বোঝানোর পরে এটির জন্য আপনাকে আপনার পুরো নির্দেশ সেটটি আবারও লিখতে হবে এবং প্রশ্নের মধ্যে তিনি সবসময় মনে রাখে না। এবং আপনার টিপসটি মনে রাখতেও অসুবিধা হয় যেমন কেবল আমাকে জিজ্ঞাসা করুন। তিনি সর্বদা আপনার লিখিত দিকনির্দেশকে যথাসাধ্য অনুসরণ করেন তবে তিনি যথাসাধ্য পারেন।
আপনি কোনও সমাধানের কথা ভাবেন, আপনি কেবল আপনার সমস্ত নির্দেশাবলীতে নিম্নলিখিতটি যুক্ত করুন:
If you have any questions about symbols, call me at extension 1234 and I will tell you its name.
এখন যখনই তার কোনও সমস্যা হয় তিনি আপনাকে কল করে জিজ্ঞাসা করেন, আপনাকে খারাপ প্রতিক্রিয়া জানানোর চেয়ে প্রক্রিয়াটি পুনরায় আরম্ভ করার চেয়ে।
ওয়েবপেজ ডাউনলোডের ক্ষেত্রে এটির মধ্যে:
আপনার প্রোগ্রামটি সেলফোনে চলে এবং ওয়েবপৃষ্ঠাটি http://www.google.com- র জন্য অনুরোধ করছে । আপনি যদি আপনার প্রোগ্রামটি সুসংগতভাবে লিখেন তবে ডেটা ডাউনলোড করতে আপনি যে ফাংশনটি লিখেছেন তা সমস্ত ডেটা ডাউনলোড না হওয়া পর্যন্ত অবিচ্ছিন্নভাবে চলতে থাকবে। এর অর্থ আপনার ইউআই রিফ্রেশ হবে না এবং মূলত হিমায়িত প্রদর্শিত হবে। যদি আপনি কলব্যাক ব্যবহার করে আপনার প্রোগ্রামটি লিখে থাকেন তবে আপনি ডেটাটির জন্য অনুরোধ করবেন এবং বলবেন "শেষ হয়ে গেলে এই ফাংশনটি কার্যকর করুন"। ফাইলটি ডাউনলোড করার সময় এটি ইউআইকে তবুও ব্যবহারকারীর ইন্টারঅ্যাকশনের অনুমতি দেয়। ওয়েবপৃষ্ঠাটি ডাউনলোড শেষ হয়ে গেলে আপনার ফলাফল ফাংশন (কলব্যাক) কল করা হয় এবং আপনি ডেটা পরিচালনা করতে পারেন।
মূলত, এটি আপনাকে কিছু অনুরোধ করতে এবং ফলাফলের জন্য অপেক্ষা করার সময় চালানো চালিয়ে যাওয়ার অনুমতি দেয়। কলব্যাক ফাংশনের মাধ্যমে ফলাফল একবার আপনার কাছে ফিরে আসার পরে, আপনি যেখানে অপারেশনটি ছেড়ে দিয়েছিলেন তা বেছে নিতে পারেন।