Javaচ্ছিক কলব্যাকগুলির জন্য জাভাস্ক্রিপ্ট স্টাইল


93

আমার কিছু ফাংশন রয়েছে যা মাঝেমধ্যে (সর্বদা নয়) একটি কলব্যাক গ্রহণ করবে এবং এটি চালাবে। কলব্যাকটি একটি ভাল শৈলীর সংজ্ঞা দেওয়া / ফাংশন করা হয়েছে কিনা তা যাচাই করা বা আরও ভাল কোনও উপায় আছে কি না?

উদাহরণ:

function save (callback){
   .....do stuff......
   if(typeof callback !== 'undefined'){
     callback();
   };
};

আধুনিক ব্রাউজারগুলিতে আপনি কেবল ব্যবহার করতে পারেন typeof callback !== undefinedতাই ছেড়ে দিন'
স্নিকব্র্যাক

4
এবং যদি আপনি কেবল কল save()? কোনও ত্রুটি বা আবরণের সতর্কতা দেবে না কারণ একটি যুক্তি অনুপস্থিত? বা এটি পুরোপুরি ঠিক আছে এবং কলব্যাক সহজভাবে undefined?
জোও পিমেন্টেল

উত্তর:


140

আমি ব্যক্তিগতভাবে পছন্দ করি

typeof callback === 'function' && callback();

typeofকমান্ড চতুর তবে এবং শুধুমাত্র জন্য ব্যবহার করা উচিত "undefined"এবং"function"

এর সাথে সমস্যাগুলি typeof !== undefinedহ'ল ব্যবহারকারী কোনও মান হিসাবে সংজ্ঞায়িত হতে পারে যা কোনও ফাংশন নয় pass


4
typeofদুষ্টু নয় এটি কখনও কখনও অস্পষ্ট, তবে আমি এটিকে ডজি বলি না। যদিও সম্মত হয়েছে যে আপনি যদি কলটিব্যাকটিকে একটি ফাংশন হিসাবে কল করতে চলেছেন তবে এটি পরীক্ষা করা ভাল যে এটি আসলে একটি ফাংশন এবং না, আপনি জানেন, একটি সংখ্যা। :-)
টিজে ক্রোডার

4
@ টিজে ক্রাউডার ডজিটি ভুল শব্দ হতে পারে, এটি বক্সিং এবং "object"95% সময় ফিরিয়ে দেওয়ার কারণে এটি সংজ্ঞাযুক্ত তবে অকেজো ।
রায়নস

4
typeofবক্সিং কারণ না। typeof "foo"হয় "string", না "object"। আপনি কেবল কোনও স্ট্রিং আদিম বা Stringবস্তু নিয়ে কাজ করছেন কিনা তা আপনি বলতে পারবেন এটিই কেবল আসল উপায় । (সম্ভবত আপনি ভাবছেন Object.prototype.toStringযা খুব সহজ , তবে বক্সিংয়ের কারণ হয়ে দাঁড়ায়))
টিজে ক্রোডার

4
&&উপায় দ্বারা বিস্ময়করভাবে idiomatic ব্যবহার ।
টিজে ক্রাউডার

@ টিজে ক্রাউডার আপনার একটি বক্তব্য রয়েছে, আমি জানি না স্ট্রিং আদিম এবং বক্সযুক্ত স্ট্রিং অবজেক্টগুলির সাথে তুলনা করার মানটি কী। এছাড়াও আমি সম্মত .toStringখোঁজার জন্য সুন্দর [[Class]]
রায়নস

50

আপনি এটি করতে পারেন:

var noop = function(){}; // do nothing.

function save (callback){
   callback = callback || noop;
   .....do stuff......
};

আপনি যদি callbackকয়েকটি জায়গায় এটি ব্যবহার করেন তবে এটি বিশেষভাবে কার্যকর ।

অতিরিক্ত হিসাবে আপনি যদি ব্যবহার করে থাকেন তবে আপনার jQueryইতিমধ্যে এর মতো একটি ফাংশন রয়েছে, এটিকে no। নুপ বলা হয়


4
আমার দৃষ্টিতে এটি সর্বাধিক মার্জিত সমাধান।
নিকোলাস লে থিয়েরি ডি'নাখিউন

4
রাজি। এটি পরীক্ষাও সহজ করে তোলে, কারণ শর্ত নেই যদি না।

6
কিন্তু এটি টাইপ ইস্যুকে সম্বোধন করে না তাই না? আমি যদি একটি অ্যারে পাস করি? না একটি স্ট্রিং?
জেরহো

4
সরলীকৃত করুনcallback = callback || function(){};
NorCalKnockOut

4
আপনি এই ঘোষণায় একটি ডিফল্ট মান দিয়ে একটি যুক্তি anচ্ছিকও করতে পারেন:function save (callback=noop) { ...
কিথ

40

সহজভাবে কর

if (callback) callback();

যদি সরবরাহ করা হয় তবে আমি কলব্যাক কল করতে পছন্দ করি না কেন এটি টাইপ যাই হোক না কেন। এটিকে নিঃশব্দে ব্যর্থ হতে দেবেন না, তাই প্রয়োগকারী জানেন যে তিনি একটি ভুল যুক্তিতে পাস করেছেন এবং এটি ঠিক করতে পারেন।


12

ইসমাস্ক্রিপ্ট।

// @param callback Default value is a noop fn.
function save(callback = ()=>{}) {
   // do stuff...
   callback();
}

3

কলব্যাককে alচ্ছিক করার পরিবর্তে কেবল একটি ডিফল্ট বরাদ্দ করুন এবং এটিকে যাই বলুন না কেন

const identity = x =>
  x

const save (..., callback = identity) {
  // ...
  return callback (...)
}

যখন ব্যবহার করা হয়

save (...)              // callback has no effect
save (..., console.log) // console.log is used as callback

এই জাতীয় শৈলিকে ধারাবাহিকতা-পাসিং স্টাইল বলা হয় । এখানে একটি আসল উদাহরণ রয়েছে, combinationsএটি একটি অ্যারে ইনপুটটির সমস্ত সম্ভাব্য সংমিশ্রণ উত্পন্ন করে

const identity = x =>
  x

const None =
  Symbol ()

const combinations = ([ x = None, ...rest ], callback = identity) =>
  x === None
    ? callback ([[]])
    : combinations
        ( rest
        , combs =>
            callback (combs .concat (combs .map (c => [ x, ...c ])))
        )

console.log (combinations (['A', 'B', 'C']))
// [ []
// , [ 'C' ]
// , [ 'B' ]
// , [ 'B', 'C' ]
// , [ 'A' ]
// , [ 'A', 'C' ]
// , [ 'A', 'B' ]
// , [ 'A', 'B', 'C' ]
// ]

কারণ combinationsধারাবাহিকতা-পাসিং শৈলীতে সংজ্ঞায়িত, উপরের কলটি কার্যকরভাবে একই the

combinations (['A', 'B', 'C'], console.log)
// [ []
// , [ 'C' ]
// , [ 'B' ]
// , [ 'B', 'C' ]
// , [ 'A' ]
// , [ 'A', 'C' ]
// , [ 'A', 'B' ]
// , [ 'A', 'B', 'C' ]
// ]

আমরা একটি কাস্টম ধারাবাহিকতাও পাশ করতে পারি যা ফলাফলের সাথে অন্য কিছু করে

console.log (combinations (['A', 'B', 'C'], combs => combs.length))
// 8
// (8 total combinations)

অবিরত-পাসিং শৈলীটি আশ্চর্যজনকভাবে মার্জিত ফলাফলের সাথে ব্যবহার করা যেতে পারে

const first = (x, y) =>
  x

const fibonacci = (n, callback = first) =>
  n === 0
    ? callback (0, 1)
    : fibonacci
        ( n - 1
        , (a, b) => callback (b, a + b)
        )
        
console.log (fibonacci (10)) // 55
// 55 is the 10th fibonacci number
// (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...)


1

আমি এই একই স্নিপেটটি দেখে বারবার ক্লান্ত হয়ে পড়েছিলাম এবং এটি লিখেছিলাম:

  var cb = function(g) {
    if (g) {
      var args = Array.prototype.slice.call(arguments); 
      args.shift(); 
      g.apply(null, args); 
    }
  };

আমি মত কাজ করে শত ফাংশন পেয়েছি

  cb(callback, { error : null }, [0, 3, 5], true);

বা যাই হোক না কেন...

আমি পুরো "এটির কার্যকারিতা নিশ্চিত করুন" কৌশল সম্পর্কে সন্দেহবাদী। একমাত্র বৈধ মানগুলি একটি ক্রিয়া বা মিথ্যা। যদি কেউ একটি শূন্য নম্বরে বা একটি খালি খালি স্ট্রিংয়ে পাস করে তবে আপনি কী করতে যাচ্ছেন? কীভাবে সমস্যা উপেক্ষা করে সমাধান করা যায়?


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

@ রায়নোস - এটি একটি খুব, খুব নির্দিষ্ট ব্যবহারের কেস। জাভাস্ক্রিপ্ট, দুর্বলভাবে টাইপ করা হচ্ছে, পার্থক্য করার ধরণগুলিতে ভাল না, এবং সাধারণত নামকরণের প্যারামিটারগুলিতে প্রকারগুলি পার্থক্য করার চেষ্টা করা এবং কলকারী কী চান তা অনুমান করার চেয়ে ভাল হয়:save( { callback : confirmProfileSaved, priority: "low" })
মালভোলিও

আমি দ্বিমত পোষণ করছি, পর্যাপ্ত ধরণের পরীক্ষার ক্ষমতা রয়েছে। আমি পদ্ধতি ওভারলোডিং পছন্দ করি, তবে এটি ব্যক্তিগত পছন্দ। এই জাতীয় জিনিস jQuery অনেক কিছু করে।
রায়নোস

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

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

1

একটি বৈধ ফাংশন ফাংশন প্রোটোটাইপের উপর ভিত্তি করে ব্যবহার করুন:

if (callback instanceof Function)

কলব্যাকটি একটি ফাংশন তা নিশ্চিত হওয়ার জন্য


0

কলব্যাক চালানোর মানদণ্ড যদি এটির সংজ্ঞায়িত হয় বা না হয় তবে আপনি ভাল আছেন। এছাড়াও, আমি এটি ছাড়াও এটি সত্যিই কোনও ফাংশন কিনা তা পরীক্ষা করার পরামর্শ দিই।


0

আমি তখন থেকে কফি-স্ক্রিপ্টে চলে এসেছি এবং ডিফল্ট যুক্তি খুঁজে পেয়েছি এই সমস্যাটি সমাধান করার একটি দুর্দান্ত উপায়

doSomething = (arg1, arg2, callback = ()->)->
    callback()

0

এটি আর্গিলজেএস দিয়ে ইজিলি করা যেতে পারে :

function save (){
  arguments = __({callback: [Function]})
.....do stuff......
  if(arguments.callback){
    callback();
  };
};
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.