$ .Wen.apply ($, কিছুআররে) কী করে?


110

আমি ডিফার্ডস এবং প্রতিশ্রুতিগুলি সম্পর্কে পড়ছি এবং সামনে আসতে থাকব $.when.apply($, someArray)। এটি ঠিক কী করে তা সম্পর্কে আমি কিছুটা অস্পষ্ট, একটি লাইনে ঠিক কাজ করে এমন একটি ব্যাখ্যা খুঁজছি (পুরো কোড স্নিপেট নয়)। এখানে কিছু প্রসঙ্গ:

var data = [1,2,3,4]; // the ids coming back from serviceA
var processItemsDeferred = [];

for(var i = 0; i < data.length; i++){
  processItemsDeferred.push(processItem(data[i]));
}

$.when.apply($, processItemsDeferred).then(everythingDone); 

function processItem(data) {
  var dfd = $.Deferred();
  console.log('called processItem');

  //in the real world, this would probably make an AJAX call.
  setTimeout(function() { dfd.resolve() }, 2000);    

  return dfd.promise();
}

function everythingDone(){
  console.log('processed all items');
}

1
.done().thenএই ক্ষেত্রে এর জায়গায় ব্যবহার করা যেতে পারে , কেবল এফওয়াইআই
কেভিন বি

2
fwiw, সেখানে একটি একক অ্যারের ক্ষণস্থায়ী অনুমতি দেয় আন্ডারস্কোর করার জন্য একটি বিলম্বিত বন্দর এর _.whenতাই আপনি ব্যবহার করার প্রয়োজন হবে নাapply
Eevee



1
ওপি তার প্রথম বাক্যে যে নিবন্ধটি উল্লেখ করেছে তা স্থানান্তরিত করেছে - এটি এখন: flaviocopes.com/blog/deferreds- এবং- প্রোমাইজস-ইন- জাভাস্ক্রিপ্টে
গ্লুকন

উত্তর:


161

.applyআর্গুমেন্টের অ্যারে সহ একটি ফাংশন কল করতে ব্যবহৃত হয়। এটি অ্যারেতে প্রতিটি উপাদান নেয় এবং প্রতিটি ফাংশনটির প্যারামিটার হিসাবে ব্যবহার করে। কোনও ফাংশনের অভ্যন্তরে .apply( this) প্রসঙ্গও পরিবর্তন করতে পারে ।

তো, নেওয়া যাক $.when। এটি "যখন এই সমস্ত প্রতিশ্রুতিগুলি সমাধান হয়ে যায় ... কিছু করুন" বলার জন্য এটি ব্যবহৃত হয়। এটি প্যারামিটারগুলির একটি অসীম (পরিবর্তনশীল) সংখ্যার প্রয়োজন।

আপনার ক্ষেত্রে, আপনার কাছে প্রতিশ্রুতির একটি বিন্যাস রয়েছে; আপনি জানেন না যে আপনি কতগুলি পরামিতিগুলিতে যাচ্ছেন $.when। অ্যারে নিজেই পাস করা $.whenকাজ করবে না কারণ এটি এর পরামিতিগুলি প্রতিশ্রুতি হিসাবে প্রত্যাশা করে, অ্যারে নয়।

এটি সেখানেই .applyআসে It এটি অ্যারে নেয় এবং $.whenপ্রতিটি উপাদানকে প্যারামিটার হিসাবে কল করে (এবং নিশ্চিত করে যে এটি / / তে thisসেট করা আছে ), তারপরে এটি সমস্ত কাজ করে :-)jQuery$


3
যখন একাধিক প্রতিশ্রুতি $। যখন পদ্ধতিতে দেওয়া হয়। তারা কোন আদেশে মৃত্যুদণ্ড কার্যকর করবে? একের পর এক নাকি সমান্তরালে?
দর্শনা

21
@ দর্শন: আপনি প্রতিশ্রুতি "চালাবেন না"। আপনি তাদের সমাধান হওয়ার জন্য অপেক্ষা করুন। এগুলি তৈরি করা হলে মৃত্যুদন্ড কার্যকর করা হয়, $.whenকেবল চালিয়ে যাওয়ার আগে তাদের সকলের সমাপ্তির জন্য অপেক্ষা করে।
রকেট হাজমাত

1
কি মধ্যে পার্থক্য সম্পর্কে $.when($, arrayOfPromises).done(...) এবং $.when(null, arrayOfPromises).done(...) (যা আমি ফোরামে প্রস্তাবিত সমাধানের উভয় পাওয়া ...)
zeroquaranta

63

$। যখন সমস্তগুলি সমাধান হয়ে যায় তখন যখন কোনও সংখ্যক পরামিতি লাগে এবং সমাধান হয়।

anyFunction .apply (thisValue, অ্যারেপ্যারামিটারগুলি) ফাংশনটিকে যেকোনও ফাংশনটিকে তার প্রসঙ্গ নির্ধারণকে কল করে ( এই ফাংশন কলটির মধ্যে এটিই হবে ) এবং অ্যারেপ্যারামিটারে সমস্ত বস্তু পৃথক পরামিতি হিসাবে পাস করে।

উদাহরণ স্বরূপ:

$.when.apply($, [def1, def2])

হিসাবে একই:

$.when(def1, def2)

কল করার প্রয়োগের পদ্ধতি আপনাকে অজানা সংখ্যক পরামিতিগুলির অ্যারে পাস করার অনুমতি দেয়। (আপনার কোড, আপনি বলছেন যে আপনি ডেটা একটি সেবা থেকে আসে, তাহলে সেই একমাত্র উপায় কল হয় $ .when )


15

এখানে, কোড পুরোপুরি ডকুমেন্টেড।

// 1. Declare an array of 4 elements
var data = [1,2,3,4]; // the ids coming back from serviceA
// 2. Declare an array of Deferred objects
var processItemsDeferred = [];

// 3. For each element of data, create a Deferred push push it to the array
for(var i = 0; i < data.length; i++){
  processItemsDeferred.push(processItem(data[i]));
}

// 4. WHEN ALL Deferred objects in the array are resolved THEN call the function
//    Note : same as $.when(processItemsDeferred[0], processItemsDeferred[1], ...).then(everythingDone);
$.when.apply($, processItemsDeferred).then(everythingDone); 

// 3.1. Function called by the loop to create a Deferred object (data is numeric)
function processItem(data) {
  // 3.1.1. Create the Deferred object and output some debug
  var dfd = $.Deferred();
  console.log('called processItem');

  // 3.1.2. After some timeout, resolve the current Deferred
  //in the real world, this would probably make an AJAX call.
  setTimeout(function() { dfd.resolve() }, 2000);    

  // 3.1.3. Return that Deferred (to be inserted into the array)
  return dfd.promise();
}

// 4.1. Function called when all deferred are resolved
function everythingDone(){
  // 4.1.1. Do some debug trace
  console.log('processed all items');
}

7
$.when.apply($, array)হয় না হিসাবে একই $.when(array)। এটি একই রকম:$.when(array[0], array[1], ...)
রকেট হাজমাত

1
অ্যাপ্লিকেশনটি ব্যবহার করার জন্য এটিই মূল কারণ , আপনি জানেন না অনেক উপাদান উপাদান প্রক্রিয়াজাতকরণডেফের্ড করেছে
পাবলো

2

দুর্ভাগ্যক্রমে আমি আপনার সাথে একমত হতে পারে না।

$.when.apply($, processItemsDeferred).always(everythingDone);

মুলতুবি থাকা অন্য মুলতুবি থাকা সত্ত্বেও কোনও everythingDoneস্থগিত হওয়া প্রত্যাখ্যান হওয়ার সাথে সাথে কল করবে ।

পুরো স্ক্রিপ্ট হেরেস (আমি প্রস্তাব করছি http://jsfiddle.net/ ):

var data = [1,2,3,4]; // the ids coming back from serviceA
var processItemsDeferred = [];

for(var i = 0; i < data.length; i++){
  processItemsDeferred.push(processItem(data[i]));
}

processItemsDeferred.push($.Deferred().reject());
//processItemsDeferred.push($.Deferred().resolve());

$.when.apply($, processItemsDeferred).always(everythingDone); 

function processItem(data) {
  var dfd = $.Deferred();
  console.log('called processItem');

  //in the real world, this would probably make an AJAX call.
  setTimeout(function() { dfd.resolve(); }, 2000);    

  return dfd.promise();
}

function everythingDone(){
  alert('processed all items');
}

এটি একটি বাগ? আমি ভদ্রলোক এটি বর্ণিত মত এটি ব্যবহার করতে চাই।


1
প্রথম প্রত্যাখ্যান সর্বদা আগুন জ্বালাবে, তবে নয়। আপনার উদাহরণ থেকে আমি তৈরি করেছি আমার jsfiddle.net/logankd/s5dacgb3 দেখুন । আমি এই উদাহরণে JQuery 2.1.0 ব্যবহার করছি।
30:30

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

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

@ গনকোডিং এই উত্তরটি নেওয়ার জন্য আপনাকে ধন্যবাদ
এমপ্যাভলাক

1
@ গনকোডিং লোল, আমি আপনার সমাধানটি পড়েছি এবং প্রতিক্রিয়া জানিয়েছি। আপনি মূল প্রশ্নের উত্তর সরবরাহ করেন নি। এটি যেমন ছিল কেন আপনি তা বিশদভাবে বলতে পারেন নি। এটি আপনার মত লোক যারা শেখার লোকদের জন্য ভয়ানক সমাধান সরবরাহ করে। আপনার কাছে স্পষ্টভাবে জাভাস্ক্রিপ্টের সীমিত দক্ষতা রয়েছে এবং আমাকে N00b হিসাবে নিয়ে যাচ্ছেন। আমি কেন এটি ভুল তা ইঙ্গিত করেছিলাম এবং আপনি কোডটি পড়তে পারেন না এবং পরিবর্তে আমাকে বলবেন যে আমি ভুল। ভাল কাজ বন্ধু!
এমপিভ্লাক

1

হতে পারে যে কেউ এটি দরকারী খুঁজে পেতে পারেন:

$.when.apply($, processItemsDeferred).then(everythingDone).fail(noGood);

সবকিছুই বাতিল হওয়ার ক্ষেত্রে ডাকা হয় না called


0

$। যখন প্রতিশ্রুতি দেওয়া প্রতিশ্রুতিগুলি সমাধান / প্রত্যাখ্যান করা হয় কেবল তখনই কলব্যাক কল করা সম্ভব হয়। সাধারণত, $ .আপনি যখন একটি পরিবর্তনশীল সংখ্যক আর্গুমেন্ট গ্রহণ করেন, তখন অ্যাপ্লিকেশন ব্যবহার করে এটি আর্গুমেন্টের অ্যারে পাস করা সম্ভব করে তোলে, এটি খুব শক্তিশালী। .Apply সম্পর্কে আরও তথ্যের জন্য: https://developer.mozilla.org/en-US/docs/ জাভা স্ক্রিপ্ট / রেফারেন্স / গ্লোবাল_অবজেক্টস / ফাংশন / অ্যাপ্লিকেশন


0

আপনার মার্জিত সমাধানের জন্য ধন্যবাদ:

var promise;

for(var i = 0; i < data.length; i++){
  promise = $.when(promise, processItem(data[i]));
}

promise.then(everythingDone);

কেবলমাত্র একটি পয়েন্ট: resolveWithকিছু পরামিতিগুলি ব্যবহার করার সময় , প্রাথমিক প্রতিশ্রুতি অপরিজ্ঞায়িত হয়ে যাওয়ার কারণে এটি ভেঙে যায়। আমি এটি কাজ করতে কি করেছি:

// Start with an empty resolved promise - undefined does the same thing!
var promise;

for(var i = 0; i < data.length; i++){
  if(i==0) promise = processItem(data[i]);
  else promise = $.when(promise, processItem(data[i]));
}

promise.then(everythingDone);

2
যদিও এটি কাজ করে, এটি সত্যিই মার্জিত নয়। আপনি প্রতিশ্রুতি তৈরি করছেন যা আপ-টু-আইথ বিলম্বিত হওয়ার জন্য প্রতিনিধিত্ব করে যাতে শেষ পুনরাবৃত্তিতে "কখন (ওয়ার্কটোডো [0..i-1], ওয়ার্কটোডো [i])" বা আরও স্পষ্টভাবে "যখন সমস্ত পূর্ববর্তী কাজ এবং এটি থাকে কাজ শেষ". এর অর্থ হ'ল আপনার প্রতিশ্রুতিগুলি মোড়ানোর সময় আপনার কাছে আই +1 থাকে। এছাড়াও, এই ধরণের স্টাফ করার সময় কেবল প্রথম পুনরাবৃত্তিটি মোড়ক করুন। var वचन = প্রক্রিয়া আইটেম (ডেটা [0]); (var i = 1; i <ডেটা দৈর্ঘ্য; i++) {প্রতিশ্রুতি = $। যখন (প্রতিশ্রুতি, প্রক্রিয়া আইটেম (ডেটা [i])); }
এমপিভলাক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.