Array.forEach
জাভাস্ক্রিপ্টের নেটিভ বাস্তবায়ন সম্পর্কে আমার একটি প্রশ্ন রয়েছে : এটি কি অ্যাসিঙ্ক্রোনালি আচরণ করে? উদাহরণস্বরূপ, যদি আমি কল করি:
[many many elements].forEach(function () {lots of work to do})
এটি কি অবরুদ্ধ হবে?
Array.forEach
জাভাস্ক্রিপ্টের নেটিভ বাস্তবায়ন সম্পর্কে আমার একটি প্রশ্ন রয়েছে : এটি কি অ্যাসিঙ্ক্রোনালি আচরণ করে? উদাহরণস্বরূপ, যদি আমি কল করি:
[many many elements].forEach(function () {lots of work to do})
এটি কি অবরুদ্ধ হবে?
উত্তর:
না, এটি ব্লক করছে। অ্যালগরিদমের স্পেসিফিকেশন একবার দেখুন ।
তবে সম্ভবত বাস্তবায়ন বোঝার জন্য আরও সহজ এমডিএন দেওয়া আছে :
if (!Array.prototype.forEach)
{
Array.prototype.forEach = function(fun /*, thisp */)
{
"use strict";
if (this === void 0 || this === null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== "function")
throw new TypeError();
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in t)
fun.call(thisp, t[i], i, t);
}
};
}
আপনার যদি প্রতিটি উপাদানটির জন্য প্রচুর কোড চালাতে হয় তবে আপনার আলাদা পদ্ধতির ব্যবহার বিবেচনা করা উচিত:
function processArray(items, process) {
var todo = items.concat();
setTimeout(function() {
process(todo.shift());
if(todo.length > 0) {
setTimeout(arguments.callee, 25);
}
}, 25);
}
এবং তারপরে এটিকে কল করুন:
processArray([many many elements], function () {lots of work to do});
এটি তখন অবরুদ্ধ হবে। উদাহরণটি উচ্চ পারফরম্যান্স জাভাস্ক্রিপ্ট থেকে নেওয়া হয়েছে ।
অন্য বিকল্প ওয়েব কর্মী হতে পারে ।
forEach
করে নাawait
এবং আপনার পরিবর্তে একটি for
লুপ ব্যবহার করা উচিত : stackoverflow.com/questions/37962880/…
await
অভ্যন্তরীণ async
ফাংশনগুলি ব্যবহার করতে পারেন । কিন্তু forEach
অ্যাসিঙ্ক ফাংশনগুলি কী তা জানেন না। মনে রাখবেন যে অ্যাসিঙ্ক ফাংশনগুলি কেবল একটি প্রতিশ্রুতি ফেরত ফাংশন। আপনি কি forEach
কলব্যাক থেকে ফিরে কোন প্রতিশ্রুতি সামলানোর আশা করবেন? forEach
কলব্যাক থেকে রিটার্ন মানটিকে সম্পূর্ণ উপেক্ষা করে। এটি কেবলমাত্র একটি অ্যাসিঙ্ক কলব্যাক পরিচালনা করতে সক্ষম হবে যদি এটি নিজেই অ্যাসিঙ্ক থাকে।
আপনার যদি এর মতো একটি অ্যাসিনক্রোনাস-বান্ধব সংস্করণ Array.forEach
এবং অনুরূপ প্রয়োজন হয় তবে সেগুলি নোড.জেএস এর ' অ্যাসিঙ্ক ' মডিউলটিতে উপলব্ধ: http://github.com/caolan/async ... বোনাস হিসাবে এই মডিউলটি ব্রাউজারেও কাজ করে ।
async.each(openFiles, saveFile, function(err){
// if any of the saves produced an error, err would equal that error
});
eachSeries
পরিবর্তে ব্যবহার করতে হবে।
নোডে সত্যিই ভারী গণনা করার জন্য একটি সাধারণ প্যাটার্ন রয়েছে যা আপনার জন্য প্রযোজ্য হতে পারে ...
নোড একক থ্রেডেড (ইচ্ছাকৃত ডিজাইনের পছন্দ হিসাবে দেখুন নোড.জেএস কি? ); এর অর্থ এটি কেবল একটি একক কোর ব্যবহার করতে পারে। আধুনিক বাক্সগুলিতে 8, 16 বা আরও বেশি কোর রয়েছে, সুতরাং এটি 90% + মেশিনকে অলস রাখতে পারে। একটি REST পরিষেবার সাধারণ প্যাটার্নটি হ'ল কোর প্রতি এক নোড প্রক্রিয়া চালিত করা এবং এগুলিকে http://nginx.org/ এর মতো স্থানীয় লোড ব্যালান্সারের পিছনে রাখা ।
একটি শিশুকে চাঙ্গা করা হচ্ছে - আপনি যা করার চেষ্টা করছেন তার জন্য আরও একটি সাধারণ প্যাটার্ন রয়েছে, ভারী উত্তোলন করতে কোনও শিশু প্রক্রিয়া বন্ধ করে দেওয়া। উত্সাহটি হ'ল বাচ্চাদের প্রক্রিয়াটি পটভূমিতে ভারী গণনা করতে পারে যখন আপনার পিতামাতার প্রক্রিয়া অন্যান্য ইভেন্টের জন্য প্রতিক্রিয়াশীল। ধরাটি হ'ল আপনি / এই শিশু প্রক্রিয়াটির সাথে মেমরি ভাগ করতে পারবেন না (প্রচুর পরিমাণে সংযোজন এবং কিছু নেটিভ কোড ছাড়াই নয়); আপনি বার্তা পাস করতে হবে। আপনার ইনপুট এবং আউটপুট ডেটার আকারটি গণনার তুলনায় তুলনামূলকভাবে তুলনামূলকভাবে কম করতে হবে তবে এটি সুন্দরভাবে কাজ করবে। এমনকি আপনি চাইল্ড নোড.জেএস প্রক্রিয়া চালিয়ে যেতে পারেন এবং আপনি আগে একই কোড ব্যবহার করতে পারেন।
উদাহরণ স্বরূপ:
var child_process = প্রয়োজনীয় ('চাইল্ড_প্রসেস'); ফাংশন রান_ইনচাইল্ড (অ্যারে, সিবি) { var প্রক্রিয়া = চাইল্ড_প্রসেস.এক্সেক ('নোড লিবিফএন.জেএস', ফাংশন (ত্রুটি, স্টডআউট, স্টার্ডার) var আউটপুট = JSON.parse (stdout); সিবি (এরর, আউটপুট); }); প্রক্রিয়া.স্টদিন.উইরাইট (JSON.stringify (অ্যারে), 'utf8'); process.stdin.end (); }
Array.forEach
কম্পিউটিং স্টাফ অপেক্ষা না করে, এবং কোনও ইভেন্ট লুপে কম্পিউটারকে অবিচ্ছিন্ন করে তোলার মতো কিছুই নেই (ওয়েবকাররা যদি মাল্টি-কোর গণনার প্রয়োজন হয় তবে মাল্টিপ্রসেসিং যুক্ত করুন)। আপনি যদি একাধিক টাস্ক শেষ হওয়ার অপেক্ষা করতে চান তবে একটি কাউন্টার ব্যবহার করুন, যা আপনি একটি সেমফোর ক্লাসে মোড়ানো করতে পারেন।
সম্পাদনা 2018-10-11: দেখে মনে হচ্ছে একটি ভাল সুযোগ আছে মান নীচে বর্ণিত মধ্য দিয়ে যেতে পারে না, বিবেচনা মত pipelineing একটি বিকল্প (ঠিক একই আচরণ করে না কিন্তু পদ্ধতি একই জমিদারি বাস্তবায়িত হতে পারে) হিসাবে।
এ কারণেই আমি এস 7 সম্পর্কে উত্সাহিত, ভবিষ্যতে আপনি নীচের কোডটির মতো কিছু করতে সক্ষম হবেন (কিছু চশমা সম্পূর্ণ নয় তাই সাবধানতার সাথে ব্যবহার করুন, আমি এটি আপডেট রাখার চেষ্টা করব)। তবে মূলত: নতুন :: বাইন্ড অপারেটরটি ব্যবহার করে আপনি কোনও অবজেক্টে কোনও পদ্ধতি চালাতে সক্ষম হবেন যেন বস্তুর প্রোটোটাইপটিতে কোনও পদ্ধতি রয়েছে। উদাহরণস্বরূপ [অবজেক্ট] :: [পদ্ধতি] যেখানে আপনি সাধারণত [অবজেক্ট] কল করবেন [[অবজেক্টস ম্যাথড]
আজ (24-জুলাই -16) এটি করার জন্য দ্রষ্টব্য এবং নিম্নলিখিত ব্রাউজারগুলিতে এটি কাজ করার জন্য আপনাকে নীচের কার্যকারিতাটির জন্য আপনার কোডটি স্থানান্তর করতে হবে: আমদানি / রফতানি , তীর ফাংশন , প্রতিশ্রুতি , অ্যাসিঙ্ক / অ্যাওয়েট এবং সর্বাধিক গুরুত্বপূর্ণভাবে ফাংশন বাইন্ড । নিচে যদি nessesary শুধুমাত্র ফাংশন বেঁধে ব্যবহার করতে modfied যেতে পারে কোড, সব এই কার্যকারিতা সুন্দরভাবে প্রাপ্তিসাধ্য আজ ব্যবহার করা Babel ।
আপনারকোড.জেএস (যেখানে ' প্রচুর কাজ করতে হবে ' অবশ্যই একটি প্রতিশ্রুতি ফিরিয়ে আনতে হবে, অ্যাসিনক্রোনাস কাজ সম্পন্ন হওয়ার পরে এটি সমাধান করতে হবে))
import { asyncForEach } from './ArrayExtensions.js';
await [many many elements]::asyncForEach(() => lots of work to do);
ArrayExtensions.js
export function asyncForEach(callback)
{
return Promise.resolve(this).then(async (ar) =>
{
for(let i=0;i<ar.length;i++)
{
await callback.call(ar, ar[i], i, ar);
}
});
};
export function asyncMap(callback)
{
return Promise.resolve(this).then(async (ar) =>
{
const out = [];
for(let i=0;i<ar.length;i++)
{
out[i] = await callback.call(ar, ar[i], i, ar);
}
return out;
});
};
এটি তৃতীয় পক্ষের libs প্রয়োজন ছাড়াই ব্যবহার করার জন্য একটি সংক্ষিপ্ত অ্যাসিনক্রোনাস ফাংশন
Array.prototype.each = function (iterator, callback) {
var iterate = function () {
pointer++;
if (pointer >= this.length) {
callback();
return;
}
iterator.call(iterator, this[pointer], iterate, pointer);
}.bind(this),
pointer = -1;
iterate(this);
};
প্রতিটি লুপের জন্য সহজ অ্যাসিনক্রোনাসের জন্য এনপিএমে একটি প্যাকেজ রয়েছে ।
var forEachAsync = require('futures').forEachAsync;
// waits for one request to finish before beginning the next
forEachAsync(['dogs', 'cats', 'octocats'], function (next, element, index, array) {
getPics(element, next);
// then after all of the elements have been handled
// the final callback fires to let you know it's all done
}).then(function () {
console.log('All requests have finished');
});
এছাড়াও AllAsync এর জন্য আরেকটি প্রকরণ
এমনকি সমাধানটিরও এভাবে কোড করা সম্ভব উদাহরণস্বরূপ:
var loop = function(i, data, callback) {
if (i < data.length) {
//TODO("SELECT * FROM stackoverflowUsers;", function(res) {
//data[i].meta = res;
console.log(i, data[i].title);
return loop(i+1, data, errors, callback);
//});
} else {
return callback(data);
}
};
loop(0, [{"title": "hello"}, {"title": "world"}], function(data) {
console.log("DONE\n"+data);
});
অন্যদিকে, এটি "ফর" এর চেয়ে অনেক ধীর গতির।
অন্যথায়, চমৎকার অ্যাসিঙ্ক লাইব্রেরি এটি করতে পারে: https://caolan.github.io/async/docs.html#each
এটি পরীক্ষা করার জন্য আপনি চালাতে পারেন এমন একটি ছোট উদাহরণ এখানে:
[1,2,3,4,5,6,7,8,9].forEach(function(n){
var sum = 0;
console.log('Start for:' + n);
for (var i = 0; i < ( 10 - n) * 100000000; i++)
sum++;
console.log('Ended for:' + n, sum);
});
এটি এর মতো কিছু তৈরি করবে (যদি এটি খুব কম / বেশি সময় নেয় তবে পুনরাবৃত্তির সংখ্যা বৃদ্ধি / হ্রাস করে):
(index):48 Start for:1
(index):52 Ended for:1 900000000
(index):48 Start for:2
(index):52 Ended for:2 800000000
(index):48 Start for:3
(index):52 Ended for:3 700000000
(index):48 Start for:4
(index):52 Ended for:4 600000000
(index):48 Start for:5
(index):52 Ended for:5 500000000
(index):48 Start for:6
(index):52 Ended for:6 400000000
(index):48 Start for:7
(index):52 Ended for:7 300000000
(index):48 Start for:8
(index):52 Ended for:8 200000000
(index):48 Start for:9
(index):52 Ended for:9 100000000
(index):45 [Violation] 'load' handler took 7285ms
ব্যবহারের Promise.each এর Bluebird গ্রন্থাগার।
Promise.each(
Iterable<any>|Promise<Iterable<any>> input,
function(any item, int index, int length) iterator
) -> Promise
এই পদ্ধতিটি একটি অ্যারের উপরে পুনরাবৃত্তি করে বা অ্যারের প্রতিশ্রুতিতে প্রদত্ত পুনরুক্তিকারীর সাথে প্রতিশ্রুতি (বা প্রতিশ্রুতি এবং মানগুলির মিশ্রণ) থাকে ফাংশন সহ স্বাক্ষর (মান, সূচক, দৈর্ঘ্য) সহ যেখানে মান কোনওটির সমাধান হওয়া মান হয় ইনপুট অ্যারে সম্পর্কিত প্রতিশ্রুতি। ধারাবাহিকভাবে Iteration ঘটে। যদি পুনরুক্তি ফাংশন কোনও প্রতিশ্রুতি বা তত্ক্ষণীয় ফিরিয়ে দেয় তবে পরবর্তী পুনরাবৃত্তিটি চালিয়ে যাওয়ার আগে প্রতিশ্রুতির ফলাফলটির জন্য অপেক্ষা করা হবে। যদি ইনপুট অ্যারেতে কোনও প্রতিশ্রুতি প্রত্যাখাত হয় তবে প্রত্যাশিত প্রতিশ্রুতিও প্রত্যাখ্যান করা হবে।
যদি সমস্ত পুনরাবৃত্তি সাফল্যের সাথে সমাধান করা হয় তবে Promise.each মূল অ্যারেটি অবিচলিতভাবে সমাধান করে । যাইহোক, যদি এক পুনরাবৃত্তির প্রত্যাখ্যান বা ত্রুটি, Promise.each মৃত্যুদন্ড অবিলম্বে ceases আর কোনও পুনরাবৃত্তিও প্রক্রিয়া নেই। ত্রুটি বা প্রত্যাখ্যাত মানটি মূল অ্যারের পরিবর্তে এই ক্ষেত্রে ফিরে আসে।
এই পদ্ধতিটি পার্শ্ব প্রতিক্রিয়াগুলির জন্য ব্যবহার করা বোঝায়।
var fileNames = ["1.txt", "2.txt", "3.txt"];
Promise.each(fileNames, function(fileName) {
return fs.readFileAsync(fileName).then(function(val){
// do stuff with 'val' here.
});
}).then(function() {
console.log("done");
});