ES6 WeakMap এর আসল ব্যবহারগুলি কী কী?


397

WeakMapECMAScript 6 এ প্রবর্তিত ডেটা স্ট্রাকচারের আসল ব্যবহারগুলি কী কী ?

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

আমার কাছে মনে হচ্ছে এটি:

weakmap.set(key, value);

... এটি বলার এক চক্রাকার উপায়:

key.value = value;

আমি কোন কংক্রিট ব্যবহারের ঘটনা অনুপস্থিত?




35
রিয়েল ওয়ার্ল্ড ইউজ কেস: ডিওএম নোডের জন্য কাস্টম ডেটা সঞ্চয় করুন।
ফেলিক্স ক্লিং

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

2
WeakMapমেমরি ফাঁস সনাক্ত করতে এস ব্যবহার করা যেতে পারে: স্টিভেনভ.ক.এ.
id=

উত্তর:


513

মৌলিকভাবে

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

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

ধরা যাক আমি এমন একটি এপিআই ব্যবহার করছি যা আমাকে একটি নির্দিষ্ট অবজেক্ট দেয়:

var obj = getObjectFromLibrary();

এখন, আমার কাছে একটি পদ্ধতি রয়েছে যা অবজেক্টটি ব্যবহার করে:

function useObj(obj){
   doSomethingWith(obj);
}

আমি নির্দিষ্ট অবজেক্টের সাথে পদ্ধতিটি কতবার কল করা হয়েছিল এবং এটি এন বারের চেয়ে বেশি হলে রিপোর্ট করাতে চাই। নিঃসন্দেহে কেউ মানচিত্র ব্যবহার করার কথা ভাববে:

var map = new Map(); // maps can have object keys
function useObj(obj){
    doSomethingWith(obj);
    var called = map.get(obj) || 0;
    called++; // called one more time
    if(called > 10) report(); // Report called more than 10 times
    map.set(obj, called);
}

এটি কাজ করে, তবে এটির একটি স্মৃতি ফাঁস রয়েছে - আমরা এখন ফাংশনে পাঠানো প্রতিটি লাইব্রেরি অবজেক্টের ট্র্যাক রাখি যা লাইব্রেরির অবজেক্টগুলিকে আবর্জনা সংগ্রহ করা থেকে রক্ষা করে। পরিবর্তে - আমরা একটি ব্যবহার করতে পারি WeakMap:

var map = new WeakMap(); // create a weak map
function useObj(obj){
    doSomethingWith(obj);
    var called = map.get(obj) || 0;
    called++; // called one more time
    if(called > 10) report(); // Report called more than 10 times
    map.set(obj, called);
}

আর স্মৃতি ফুটো হয়ে যায়।

ব্যবহারের ক্ষেত্রে

কিছু কিছু ক্ষেত্রে ব্যবহার করে যা অন্যথায় মেমরি ফাঁস হতে পারে এবং এর দ্বারা সক্ষম করা WeakMapরয়েছে:

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

আসুন একটি বাস্তব ব্যবহার তাকান

এটি বাইরে থেকে কোনও বস্তু প্রসারিত করতে ব্যবহার করা যেতে পারে। আসুন নোড.জেএস এর বাস্তব জগতের থেকে একটি ব্যবহারিক (অভিযোজিত, প্রকারের বাস্তব - একটি বিন্দু) উদাহরণ দিন।

ধরা যাক আপনি নোড.জেস এবং আপনার কাছে Promiseবস্তু রয়েছে - এখন আপনি বর্তমানে প্রত্যাখ্যাত সমস্ত প্রতিশ্রুতিগুলি ট্র্যাক রাখতে চান - তবে কোনও উল্লেখের অস্তিত্ব না থাকলে আপনি তাদের আবর্জনা সংগ্রহ থেকে আটকাতে চান না

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

WeakMaps লিখুন

WeakMaps এর অর্থ কীগুলি দুর্বল। কোনও দুর্বল মানচিত্র গণনা করার বা তার সমস্ত মান পাওয়ার কোনও উপায় নেই। একটি দুর্বল মানচিত্রে, আপনি কোনও কীটির উপর ভিত্তি করে ডেটা সঞ্চয় করতে পারেন এবং কীটি যখন আবর্জনা সংগ্রহ করে তা মানগুলি করে।

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

এই প্রয়োগ করতে ব্যবহৃত হয় অপরিচালিত প্রত্যাখ্যান আঙ্গুলসমূহ যেমন Petka Antonov দ্বারা এই :

process.on('unhandledRejection', function(reason, p) {
    console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
    // application specific logging, throwing an error, or other logic here
});

আমরা মানচিত্রে প্রতিশ্রুতি সম্পর্কিত তথ্য রাখি এবং কখন প্রত্যাখ্যাত প্রতিশ্রুতি পরিচালনা করা হয় তা জানতে পারি।


8
হ্যালো! আপনি দয়া করে আমাকে বলতে পারেন যে উদাহরণ কোডটির কোন অংশটি মেমরি ফাঁসির কারণ?
ltamajs

15
@ ltamajs4 নিশ্চিত, useObjউদাহরণ হিসাবে একটি Mapএবং না WeakMapব্যবহার করে আমরা মানচিত্র কী হিসাবে অবজেক্টে উত্তীর্ণকে ব্যবহার করি। বস্তুটি কখনই মানচিত্র থেকে সরানো হয় না (যেহেতু কখন তা করতে হবে তা আমরা জানতাম না) তাই সর্বদা এর উল্লেখ থাকে এবং এটি কখনই আবর্জনা সংগ্রহ করা যায় না। WeakMap উদাহরণে অবজেক্টের সাথে অন্যান্য সমস্ত রেফারেন্সগুলি চলে যাওয়ার সাথে সাথে - অবজেক্টটি ক্লিয়ার করা যেতে পারে WeakMap। আপনি যদি এখনও নিশ্চিত না হন তবে আমি কী বলতে চাই তা দয়া করে আমাকে জানান
বেনজামিন গ্রুইনবাউম

@ বেঞ্জামিন, আমাদের একটি স্মৃতি-সংবেদনশীল ক্যাশের প্রয়োজন এবং ডেটা_বজেক্ট টিউপলের প্রয়োজনের মধ্যে পার্থক্য করতে হবে। এই দুটি পৃথক প্রয়োজনীয়তা পূরণ করবেন না। আপনার calledউদাহরণটি jsfiddle.net/f2efbm7z ব্যবহার করে আরও ভাল লেখা হয়েছে এবং এটি কোনও দুর্বল মানচিত্রের ব্যবহার প্রদর্শন করে না। আসলে, এটি মোট 6 উপায়ে আরও ভাল লেখা যেতে পারে , যা আমি নীচে তালিকাবদ্ধ করব।
পেসারিয়ার

মূলত, দুর্বল মানচিত্রের উদ্দেশ্য একটি মেমরি-সংবেদনশীল ক্যাশে। যদিও এটি বাইরে থেকে জিনিসগুলি প্রসারিত করার জন্য ব্যবহার করা যেতে পারে, এটি একটি অপ্রত্যাশিত লসি হ্যাক এবং এটি অবশ্যই এর সঠিক উদ্দেশ্য নয়
পেসারিয়ার

1
আপনি যদি কোনও প্রতিশ্রুতি এবং যে বার পরিচালনা করেছেন / প্রত্যাখ্যান করেছেন তার সংখ্যার মধ্যে লিঙ্কটি রাখতে চান তবে 1) চিহ্ন ব্যবহার করুন ; p[key_symbol] = data। বা 2) অনন্য নামকরণ; p.__key = data। বা 3) ব্যক্তিগত সুযোগ; (()=>{let data; p.Key = _=>data=_;})()। বা 4) 1 বা 2 বা 3. বা 5 এর সাথে প্রক্সি ) প্রতিশ্রুতি শ্রেণি 1 বা 2 বা 3 বা 3 বা প্রতিস্থাপন / প্রসারিত করুন ) প্রয়োজনীয় সদস্যদের একটি দ্বিগুণ সহ প্রতিশ্রুতি শ্রেণি প্রতিস্থাপন / প্রসারিত করুন। - যাইহোক , আপনার স্মৃতি সংবেদনশীল ক্যাশে না লাগলে দুর্বল মানচিত্রের প্রয়োজন হবে না।
পেসারিয়ার

48

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

শ্রোতাদের জন্য অভিধান হিসাবে এটি ব্যবহারের ক্ষেত্রে ব্যবহারের ক্ষেত্রে হতে পারে, আমার এক সহকর্মী আছেন যিনি এটি করেছিলেন। এটি খুব সহায়ক কারণ যে কোনও শ্রোতা সরাসরি এই জিনিসগুলি করার জন্য লক্ষ্যযুক্ত। বিদায় listener.on

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


এরপরে কী পড়ার আগে

আমি এখন বুঝতে পারি যে আমার জোর দেওয়া সমস্যাটি মোকাবেলার হুবহু সেরা উপায় নয় এবং যেমন বেঞ্জামিন গ্রুইনবাউম নির্দেশ করেছেন (তার উত্তরটি দেখুন, এটি ইতিমধ্যে আমার উপরে না থাকলে: পি) Map, যেহেতু এই সমস্যাটি কোনও নিয়মিত দিয়ে সমাধান করা যেত না since এটি ফাঁস হয়ে যেত, সুতরাং এর প্রধান শক্তিটি WeakMapহ'ল তারা কোনও রেফারেন্স না রাখার কারণে আবর্জনা সংগ্রহের ক্ষেত্রে হস্তক্ষেপ করে না।


এখানে আমার সহকর্মীর আসল কোড ( ভাগ করে নেওয়ার জন্য তাকে ধন্যবাদ )

এখানে সম্পূর্ণ উত্স , এটি শ্রোতা পরিচালনার বিষয়ে যা আমি উপরে আলোচনা করেছি (আপনি চশমাটি একবার দেখে নিতে পারেন )

var listenableMap = new WeakMap();


export function getListenable (object) {
    if (!listenableMap.has(object)) {
        listenableMap.set(object, {});
    }

    return listenableMap.get(object);
}


export function getListeners (object, identifier) {
    var listenable = getListenable(object);
    listenable[identifier] = listenable[identifier] || [];

    return listenable[identifier];
}


export function on (object, identifier, listener) {
    var listeners = getListeners(object, identifier);

    listeners.push(listener);
}


export function removeListener (object, identifier, listener) {
    var listeners = getListeners(object, identifier);

    var index = listeners.indexOf(listener);
    if(index !== -1) {
        listeners.splice(index, 1);
    }
}


export function emit (object, identifier, ...args) {
    var listeners = getListeners(object, identifier);

    for (var listener of listeners) {
        listener.apply(object, args);
    }
}

2
আপনি এটি কীভাবে ব্যবহার করবেন তা আমি যথেষ্টভাবে পাই না। এটি যখন আর রেফারেন্স করা হয় না তখন পর্যবেক্ষণযোগ্যদের সাথে আবদ্ধ ইভেন্টগুলির সাথে ধসে পড়ে। আমার যে সমস্যাটি দেখা দেয় তা হ'ল পর্যবেক্ষক আর উল্লেখ করা হয় না। আমি মনে করি যে সমাধানটি এখানে অর্ধেক সমস্যার সমাধান করে। আমি মনে করি না আপনি ওয়েকম্যাপের সাহায্যে পর্যবেক্ষকের সমস্যাটি সমাধান করতে পারবেন কারণ এটি পুনরাবৃত্তিযোগ্য নয়।
jgmjgm

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

@ এক্সেলডুচ, বাহ এই শ্রোতা-পরিচালনা কল্পকাহিনীটি জাভাস্ক্রিপ্ট সম্প্রদায়ের সমস্ত উপায়ে প্যাডেল করা হয়েছে, 40 টি উর্ধ্বে! বোঝার জন্য কেন এই উত্তর সম্পূর্ণ ভুল অধীন মন্তব্য দেখতে stackoverflow.com/a/156618/632951
Pacerier

1
@ পেসারিয়র উত্তরটি আপডেট করেছেন, প্রতিক্রিয়ার জন্য ধন্যবাদ
axelduch

1
@ ফিল্ডচ, হ্যাঁ, সেখান থেকেও একটি রেফারেন্স রয়েছে।
পেসিয়ার

18

WeakMap এনক্যাপসুলেশন এবং তথ্য গোপনের জন্য ভাল কাজ করে

WeakMapকেবলমাত্র ES6 এবং তারপরের জন্য উপলব্ধ। এ WeakMapহ'ল কী এবং মান জোড়াগুলির সংগ্রহ যেখানে কীটি অবশ্যই একটি অবজেক্ট হতে হবে। নিম্নলিখিত উদাহরণে, আমরা WeakMapদুটি আইটেম সহ একটি তৈরি করি :

var map = new WeakMap();
var pavloHero = {first: "Pavlo", last: "Hero"};
var gabrielFranco = {first: "Gabriel", last: "Franco"};
map.set(pavloHero, "This is Hero");
map.set(gabrielFranco, "This is Franco");
console.log(map.get(pavloHero));//This is Hero

আমরা set()একটি অবজেক্ট এবং অন্য আইটেমের (আমাদের ক্ষেত্রে একটি স্ট্রিং) মধ্যে সংযুক্তি সংজ্ঞা দেওয়ার জন্য পদ্ধতিটি ব্যবহার করেছি । আমরা get()কোনও অবজেক্টের সাথে সম্পর্কিত আইটেমটি পুনরুদ্ধার করার জন্য পদ্ধতিটি ব্যবহার করেছি । WeakMapS এর আকর্ষণীয় দিকটি হ'ল এটি মানচিত্রের ভিতরে থাকা কীটির প্রতি দুর্বল রেফারেন্স ধারণ করে। একটি দুর্বল রেফারেন্সের অর্থ হ'ল যদি বস্তুটি ধ্বংস হয়ে যায়, আবর্জনা সংগ্রহকারী সম্পূর্ণরূপে এন্ট্রি সরিয়ে ফেলবে WeakMap, এভাবে মেমরি মুক্ত করে।

var TheatreSeats = (function() {
  var priv = new WeakMap();
  var _ = function(instance) {
    return priv.get(instance);
  };

  return (function() {
      function TheatreSeatsConstructor() {
        var privateMembers = {
          seats: []
        };
        priv.set(this, privateMembers);
        this.maxSize = 10;
      }
      TheatreSeatsConstructor.prototype.placePerson = function(person) {
        _(this).seats.push(person);
      };
      TheatreSeatsConstructor.prototype.countOccupiedSeats = function() {
        return _(this).seats.length;
      };
      TheatreSeatsConstructor.prototype.isSoldOut = function() {
        return _(this).seats.length >= this.maxSize;
      };
      TheatreSeatsConstructor.prototype.countFreeSeats = function() {
        return this.maxSize - _(this).seats.length;
      };
      return TheatreSeatsConstructor;
    }());
})()

4
পুনরায় "এনক্যাপসুলেশন এবং তথ্য গোপনের জন্য দুর্বলম্যাপ ভাল কাজ করে"। আপনি পারছেন বলে কেবল তার মানে নয়। জাভাস্ক্রিপ্টে দুর্বলম্যাপ উদ্ভাবনের আগেই এনক্যাপসুলেশন এবং তথ্য গোপনের করার ডিফল্ট পদ্ধতি রয়েছে। বর্তমানে হিসাবে, এটি করার জন্য আক্ষরিকভাবে 6 টি উপায় রয়েছে । এনক্যাপসুলেশন করতে দুর্বলম্যাপ ব্যবহার করা একটি কুশ্রী ফেসপাম।
পেসারিয়ার

12

𝗠𝗲𝘁𝗮𝗱𝗮𝘁𝗮

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

𝗪𝗲𝗮𝗸𝗠𝗮𝗽𝘀 𝗼𝗿 𝗪𝗲𝗮𝗸𝗦𝗲𝘁𝘀:

var elements = document.getElementsByTagName('*'),
  i = -1, len = elements.length;

while (++i !== len) {
  // Production code written this poorly makes me want to cry:
  elements[i].lookupindex = i;
  elements[i].elementref = [];
  elements[i].elementref.push( elements[(i * i) % len] );
}

// Then, you can access the lookupindex's
// For those of you new to javascirpt, I hope the comments below help explain 
// how the ternary operator (?:) works like an inline if-statement
document.write(document.body.lookupindex + '<br />' + (
    (document.body.elementref.indexOf(document.currentScript) !== -1)
    ? // if(document.body.elementref.indexOf(document.currentScript) !== -1){
    "true"
    : // } else {
    "false"
  )   // }
);

𝗪𝗲𝗮𝗸𝗠𝗮𝗽𝘀 𝗮𝗻𝗱 𝗪𝗲𝗮𝗸𝗦𝗲𝘁𝘀:

var DOMref = new WeakMap(),
  __DOMref_value = Array,
  __DOMref_lookupindex = 0,
  __DOMref_otherelement = 1,
  elements = document.getElementsByTagName('*'),
  i = -1, len = elements.length, cur;

while (++i !== len) {
  // Production code written this greatly makes me want to 😊:
  cur = DOMref.get(elements[i]);
  if (cur === undefined)
    DOMref.set(elements[i], cur = new __DOMref_value)

  cur[__DOMref_lookupindex] = i;
  cur[__DOMref_otherelement] = new WeakSet();
  cur[__DOMref_otherelement].add( elements[(i * i) % len] );
}

// Then, you can access the lookupindex's
cur = DOMref.get(document.body)
document.write(cur[__DOMref_lookupindex] + '<br />' + (
    cur[__DOMref_otherelement].has(document.currentScript)
    ? // if(cur[__DOMref_otherelement].has(document.currentScript)){
    "true"
    : // } else {
    "false"
  )   // }
);

𝗗𝗶𝗳𝗳𝗲𝗿𝗲𝗻𝗰𝗲 𝗗𝗶𝗳𝗳𝗲𝗿𝗲𝗻𝗰𝗲

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

এগুলির জন্য পলিফিল হিসাবে, আমি আমার নিজের লাইব্রেরিটি সুপারিশ করব ( এখানে @ গিথুব পাওয়া যাবে )। এটি একটি খুব লাইটওয়েট লাইব্রেরি যা অন্য পলিফিলগুলিতে আপনি খুঁজে পেতে পারেন এমন কোনও অতিরিক্ত-জটিল ফ্রেমওয়ার্ক ছাড়া কেবল পলিফিল করে।

~ শুভ কোডিং!


1
পরিষ্কার ব্যাখ্যার জন্য ধন্যবাদ। একটি উদাহরণ যে কোনও শব্দের চেয়ে বেশি মূল্যবান।
newguy

@lolzery পুনরায় " বাধা দেয় আবর্জনা হচ্ছে সংগৃহীত DOM উপাদানে ", আপনার প্রয়োজন হয় সেট elementsনাল করতে এবং আপনার কাজ সম্পন্ন: এটা GCed হবেন। " ডম রেফারেন্সগুলি যা সমস্ত দস্তাবেজটিতে বাউন্স করে " পুনরায় & পুনরায় করুন , তাতে মোটেই কিছু আসে যায় না: মূল লিঙ্কটি শেষ হয়ে গেলে , সমস্ত বৃত্তাকার রেফিকে জিসিড করা হবে। যদি আপনার উপাদানটি এমন উপাদানের রেফারেন্স ধরে রাখে যেগুলির এটির প্রয়োজন হয় না, তবে কোডটি ঠিক করুন এবং রেফটি সেট করে যখন আপনি এটি ব্যবহারের সাথে সম্পন্ন করবেন তখন সেট করুন । এটা GCed হবে। Weakmaps প্রয়োজন নেইelements
পেসারিয়ার

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

1
নামযুক্ত ওয়ার্স সহ প্রোডাকশন কোডটি আমাকে বমি করে
বার্বু বার্বু

10

আমি ব্যবহার করি WeakMap অবিচ্ছিন্ন বস্তুগুলিকে তাদের প্যারামিটার হিসাবে গ্রহণ করে এমন ক্রিয়াকলাপগুলির চিন্তামুক্ত স্মৃতিচারণের ক্যাশে ।

স্মৃতিচারণ হ'ল অভিনব উপায় "আপনি মানটি গণনা করার পরে এটি ক্যাশে করুন যাতে আপনাকে এটি আবার গণনা করতে হবে না"।

এখানে একটি উদাহরণ:

কয়েকটি বিষয় লক্ষণীয়:

  • Immutable.js অবজেক্টস নতুন বস্তুগুলি (নতুন পয়েন্টার সহ) ফেরত দেয় যখন আপনি এগুলিকে পরিবর্তন করেন যাতে তাদের উইকম্যাপে কী হিসাবে ব্যবহার করা হয় একই গণিত মানের গ্যারান্টি দেয়।
  • উইকম্যাপ স্মৃতিগুলির জন্য দুর্দান্ত কারণ কারণ একবারে যখন বস্তুটি (কী হিসাবে ব্যবহৃত হয়) আবর্জনা সংগ্রহ করা হয়ে যায়, তেমনি উইকম্যাপে গণনা করা মান হয়।

1
মেমোয়াইজেশন ক্যাশে মেমরি-সংবেদনশীল হতে বোঝানো যতক্ষণ অবজেক্ট / ক্রিয়াকলাপ জুড়েই স্থির থাকে না এটি দুর্বল মানচিত্রের বৈধ ব্যবহার । যদি "মেমোয়াইজেশন ক্যাশে" বোঝানো হয় উদ্দেশ্য / ক্রিয়াকলাপের সমস্ত জীবন জুড়ে অবিচল থাকা, তবে দুর্বল ম্যাপটি ভুল পছন্দ: পরিবর্তে 6 টি ডিফল্ট জাভাস্ক্রিপ্ট এনক্যাপসুলেশন কৌশল ব্যবহার করুন।
পেসারিয়ার

3

আমার কাছে এই সাধারণ বৈশিষ্ট্য ভিত্তিক ব্যবহারের কেস / উইকম্যাপগুলির উদাহরণ রয়েছে।

ব্যবহারকারীদের একটি সংগ্রহ পরিচালনা করুন

আমি দিয়ে অনুষ্ঠানটি শুরু Userঅবজেক্ট যার বৈশিষ্ট্য একটি অন্তর্ভুক্ত fullname, username, age, genderএবং একটি পদ্ধতি বলা printযা অন্যান্য বৈশিষ্ট্য পাঠযোগ্য সারসংক্ষেপ ছাপে।

/**
Basic User Object with common properties.
*/
function User(username, fullname, age, gender) {
    this.username = username;
    this.fullname = fullname;
    this.age = age;
    this.gender = gender;
    this.print = () => console.log(`${this.fullname} is a ${age} year old ${gender}`);
}

আমি তখন usersএকাধিক ব্যবহারকারীর সংকলন রাখার জন্য একটি মানচিত্র যুক্ত করেছি যা দ্বারা কী রয়েছে username

/**
Collection of Users, keyed by username.
*/
var users = new Map();

সংযোজন যোগ করার জন্য কোনও ব্যবহারকারীকে যুক্ত করতে, পেতে, মুছতে এবং এমনকি সম্পূর্ণরূপে সমস্ত ব্যবহারকারীদের মুদ্রণের জন্য একটি ফাংশনও সহায়তা ফাংশন প্রয়োজন।

/**
Creates an User Object and adds it to the users Collection.
*/
var addUser = (username, fullname, age, gender) => {
    let an_user = new User(username, fullname, age, gender);
    users.set(username, an_user);
}

/**
Returns an User Object associated with the given username in the Collection.
*/
var getUser = (username) => {
    return users.get(username);
}

/**
Deletes an User Object associated with the given username in the Collection.
*/
var deleteUser = (username) => {
    users.delete(username);
}

/**
Prints summary of all the User Objects in the Collection.
*/
var printUsers = () => {
    users.forEach((user) => {
        user.print();
    });
}

উপরের সমস্ত কোড চলমান থাকায়, নোডজেএস বলুন , কেবলমাত্র usersমানচিত্রে পুরো প্রক্রিয়াটির মধ্যে ব্যবহারকারী অবজেক্টের রেফারেন্স রয়েছে। স্বতন্ত্র ব্যবহারকারী বিষয়গুলির জন্য অন্য কোনও রেফারেন্স নেই।

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

বিদ্যমান কোডের পরিবর্তনের পরিবর্তে ব্যবহারকারীদের আরও তথ্য যুক্ত করুন

এখন বলুন যে প্রতিটি ব্যবহারকারী সোশ্যাল মিডিয়া প্ল্যাটফর্ম (এসএমপি) লিংকগুলি ব্যবহারকারী অবজেক্টের পাশাপাশি ট্র্যাক করা দরকার a

এখানে কীটি হ'ল এই বৈশিষ্ট্যটি অবশ্যই বিদ্যমান কোডটিতে ন্যূনতম হস্তক্ষেপের সাথে প্রয়োগ করতে হবে।

নিম্নলিখিত পদ্ধতিতে WeakMaps এর মাধ্যমে এটি সম্ভব।

আমি টুইটার, ফেসবুক, লিংকডইন এর জন্য পৃথক তিনটি ওয়েকম্যাপস যুক্ত করি।

/*
WeakMaps for Social Media Platforms (SMPs).
Could be replaced by a single Map which can grow
dynamically based on different SMP names . . . anyway...
*/
var sm_platform_twitter = new WeakMap();
var sm_platform_facebook = new WeakMap();
var sm_platform_linkedin = new WeakMap();

একটি সহায়ক ফাংশন, getSMPWeakMapপ্রদত্ত এসএমপি নামের সাথে যুক্ত উইকম্যাপটি ফিরিয়ে দিতে কেবল যুক্ত করা হয়।

/**
Returns the WeakMap for the given SMP.
*/
var getSMPWeakMap = (sm_platform) => {
    if(sm_platform == "Twitter") {
        return sm_platform_twitter;
    }
    else if(sm_platform == "Facebook") {
        return sm_platform_facebook;
    }
    else if(sm_platform == "LinkedIn") {
        return sm_platform_linkedin;
    }
    return undefined;
}

প্রদত্ত এসএমপি ওয়েকম্যাপে ব্যবহারকারীদের এসএমপি লিঙ্ক যুক্ত করার জন্য একটি ফাংশন।

/**
Adds a SMP link associated with a given User. The User must be already added to the Collection.
*/
var addUserSocialMediaLink = (username, sm_platform, sm_link) => {
    let user = getUser(username);
    let sm_platform_weakmap = getSMPWeakMap(sm_platform);
    if(user && sm_platform_weakmap) {
        sm_platform_weakmap.set(user, sm_link);
    }
}

প্রদত্ত এসএমপি-তে কেবল উপস্থিত ব্যবহারকারীদের মুদ্রণের জন্য একটি ফাংশন।

/**
Prints the User's fullname and corresponding SMP link of only those Users which are on the given SMP.
*/
var printSMPUsers = (sm_platform) => {
    let sm_platform_weakmap = getSMPWeakMap(sm_platform);
    console.log(`Users of ${sm_platform}:`)
    users.forEach((user)=>{
        if(sm_platform_weakmap.has(user)) {
            console.log(`\t${user.fullname} : ${sm_platform_weakmap.get(user)}`)
        }
    });
}

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

... পূর্ববর্তী উদাহরণটি দিয়ে চালিয়ে আমি ব্যবহারকারীদের সাথে এসএমপি লিঙ্কগুলি যুক্ত করি, ব্যবহারকারীগণ বিল এবং সারার জন্য একাধিক লিঙ্ক এবং তারপরে প্রতিটি এসএমপির জন্য লিঙ্কগুলি আলাদাভাবে মুদ্রণ করি: ব্যবহারকারীদের মধ্যে এসএমপি লিঙ্ক যুক্ত করা এবং তাদের প্রদর্শন করা

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

... উদাহরণ সহকারে চালিয়ে, আমি ব্যবহারকারীর বিলটি মুছুন এবং তারপরে তিনি যে এসএমপিগুলির সাথে যুক্ত ছিলেন তার লিঙ্কগুলি মুদ্রণ করব:

মানচিত্র থেকে ব্যবহারকারীর বিল মোছার সাথে সাথে এসএমপি লিঙ্কগুলিও মুছে ফেলা হবে

আলাদাভাবে এসএমপি লিঙ্কটি আলাদাভাবে মুছতে কোনও অতিরিক্ত কোডের প্রয়োজন নেই এবং বিদ্যমান কোডটি কোনওভাবেই এই বৈশিষ্ট্যটি সংশোধন করা হয়নি।

WeakMaps এর সাথে / ছাড়া এই বৈশিষ্ট্যটি যুক্ত করার অন্য কোনও উপায় থাকলে দয়া করে বিনা দ্বিধায় মন্তব্য করুন।


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