নোড.জেসের নেটিভ প্রতিশ্রুতি কি সমস্ত সমান্তরাল বা ক্রমানুসারে প্রসেসিং হয়?


173

আমি এই বিষয়টি স্পষ্ট করে বলতে চাই, কারণ ডকুমেন্টেশনগুলি এটি সম্পর্কে খুব পরিষ্কার নয়;

চতুর্থাংশ 1: হয় Promise.all(iterable)প্রক্রিয়াকরণের সব প্রতিশ্রুতি ক্রমানুসারে বা সমান্তরাল? বা আরও সুনির্দিষ্টভাবে বলা যায়, এটি যেমন শৃঙ্খলাবদ্ধ প্রতিশ্রুতিগুলি চালনার সমতুল্য

p1.then(p2).then(p3).then(p4).then(p5)....

অথবা এটি আলগোরিদিম কিছু অন্য ধরনের যেখানে সব p1, p2, p3, p4, p5, ইত্যাদি একই সময়ে (সমান্তরাল) নামক হচ্ছে এবং ফলাফল সব সমাধান (অথবা এক প্রত্যাখ্যান) হিসাবে যত তাড়াতাড়ি ফিরে হয়?

প্রশ্ন 2: যদি Promise.allসমান্তরালভাবে চালিত হয়, তবে পুনরাবৃত্তিক্রমিক ক্রমান্বয়ে চালানোর জন্য কি কোনও সুবিধাজনক উপায় আছে?

দ্রষ্টব্য : আমি Q, বা ব্লুবার্ড ব্যবহার করতে চাই না, তবে সমস্ত নেটিভ ES6 চশমা।


আপনি নোড (ভি 8) বাস্তবায়ন সম্পর্কে জিজ্ঞাসা করছেন, বা স্পেক সম্পর্কে?
অমিত

1
আমি বেশ নিশ্চিত যে Promise.allএগুলি সমান্তরালে চালিত করে।
রোহিউই

@ অ্যামিট আমি পতাকাঙ্কিত করেছি node.jsএবং এটিই আমি io.jsএটি ব্যবহার করছি। সুতরাং, হ্যাঁ, আপনি যদি ভি 8 বাস্তবায়ন করেন।
ইয়ানিক রোচন

9
প্রতিশ্রুতি "কার্যকর করা যায় না"। যখন তারা তৈরি করা হচ্ছে তখন তারা তাদের কাজটি শুরু করে - তারা কেবল ফলাফলগুলি উপস্থাপন করে - এবং আপনি সমস্ত কিছু সমান্তরালে সম্পাদন করার আগেও তা চালিয়ে যাচ্ছেন Promise.all
বার্গি

প্রতিশ্রুতি সৃষ্টির মুহুর্তে কার্যকর করা হয়। (কিছুটা কোড চালিয়ে নিশ্চিত করা যেতে পারে)। ইন new Promise(a).then(b); c();একটি প্রথম মৃত্যুদন্ড কার্যকর করা হয়, তাহলে C, তারপর খ। এটি প্রতিশ্রুতি নয় all সমস্ত প্রতিশ্রুতিগুলি চালায়, তারা যখন সমাধান করবে তখনই এটি পরিচালনা করে।
মাটোন 1

উত্তর:


257

হয় Promise.all(iterable)সব প্রতিশ্রুতি নির্বাহ?

না, প্রতিশ্রুতিগুলি "কার্যকর করা যায় না"। যখন তারা তৈরি করা হচ্ছে তখন তারা তাদের কাজটি শুরু করে - তারা কেবল ফলাফলগুলি উপস্থাপন করে - এবং আপনি সমস্ত কিছু সমান্তরালে সম্পাদন করার আগেও তা চালিয়ে যাচ্ছেন Promise.all

Promise.allশুধুমাত্র একাধিক প্রতিশ্রুতি অপেক্ষা করে। তারা কোন ক্রমটি সমাধান করে, বা গণনাগুলি সমান্তরালে চলছে কিনা তা বিবেচ্য নয়।

পুনরাবৃত্তিযোগ্য ধারাবাহিকভাবে চালানোর জন্য কি কোনও সুবিধাজনক উপায় আছে?

আপনার যদি ইতিমধ্যে আপনার প্রতিশ্রুতি থাকে তবে আপনি বেশি কিছু করতে পারবেন না তবে Promise.all([p1, p2, p3, …])(যার ক্রমের কোনও ধারণা নেই)। তবে অ্যাসিক্রোনাস ফাংশনগুলির যদি আপনার পুনরাবৃত্তিযোগ্য হয়, তবে আপনি প্রকৃতপক্ষে সেগুলি চালিয়ে যেতে পারেন run মূলত আপনার কাছ থেকে আসা দরকার

[fn1, fn2, fn3, …]

প্রতি

fn1().then(fn2).then(fn3).then(…)

এবং এটি করার সমাধানটি ব্যবহার করছে Array::reduce:

iterable.reduce((p, fn) => p.then(fn), Promise.resolve())

1
এই উদাহরণস্বরূপ, আপনি কল করতে চান যে প্রতিশ্রুতি ফেরত ফাংশন একটি অ্যারে পুনরাবৃত্তিযোগ্য?
জেমস রেটেগই

2
@ এসএসএইচটি: এটি যথাযথ thenক্রম হিসাবে - রিটার্নের মান হ'ল শেষ fnফলাফলের প্রতিশ্রুতি , এবং আপনি অন্যান্য কলব্যাকগুলি শৃঙ্খলিত করতে পারেন।
বার্গি

1
@Wjjas এটি ঠিক সমান fn1().then(p2).then(fn3).catch(…? কোনও ফাংশন এক্সপ্রেশন ব্যবহার করার দরকার নেই।
বার্গি

1
@wjjas অবশ্যই retValFromF1পাস হয়েছে p2, ঠিক এটিই p2ঘটে। অবশ্যই, যদি আপনি আরও কিছু করতে চান (অতিরিক্ত ভেরিয়েবলগুলি পাস করুন, একাধিক ফাংশন কল করুন ইত্যাদি) আপনার একটি ফাংশন এক্সপ্রেশন ব্যবহার করতে হবে, যদিও p2অ্যারেতে পরিবর্তন করা সহজ হবে
বার্গি

1
@ robe007 হ্যাঁ, আমি যে বোঝানো iterableহয় [fn1, fn2, fn3, …]অ্যারের
Bergi

62

সমান্তরাল

await Promise.all(items.map(async item => { await fetchItem(item) }))

সুবিধা: দ্রুততর। একটি ব্যর্থ হলেও সমস্ত পুনরাবৃত্তি কার্যকর করা হবে।

ক্রমানুসারে

for (let i = 0; i < items.length; i++) {
    await fetchItem(items[i])
}

সুবিধা: লুপের পরিবর্তনশীলগুলি প্রতিটি পুনরাবৃত্তির মাধ্যমে ভাগ করা যায়। সাধারণ আবশ্যক সিঙ্ক্রোনাস কোডের মতো আচরণ করে।


7
বা:for (const item of items) await fetchItem(item);
রবার্ট পেনার 21

1
@ ডেভিড_এডলার সমান্তরাল উদাহরণ সুবিধাগুলিতে আপনি বলেছিলেন যে সমস্ত পুনরাবৃত্তি একটিতে ব্যর্থ হলেও কার্যকর করা হবে । আমি যদি ভুল না করি তবে এটি দ্রুত ব্যর্থ হবে। এই আচরণটি পরিবর্তন করতে এমন কিছু করতে পারেন: await Promise.all(items.map(async item => { return await fetchItem(item).catch(e => e) }))
তাইমুর oor

@ তাইমুর হ্যাঁ এটি "দ্রুত ব্যর্থ" হয় এবং প্রতিশ্রুতির পরে কোডটি কার্যকর করা চালিয়ে যায় all তবে সমস্ত পুনরাবৃত্তিগুলি এখনও কোডেপেন.আইও
এমএফবিএক্সএইডি 4 /

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

নোট করুন যে জাভাস্ক্রিপ্ট আসলে থ্রেড ব্যবহার করে "সমান্তরাল" তে অ্যাসিনক্রোনাস অনুরোধগুলি কার্যকর করছে না কারণ জাভাস্ক্রিপ্ট একক থ্রেডযুক্ত। বিকাশকারী.মোজিলা.আর.ওএন-
ইউএস

11

বার্গিস উত্তরটি অ্যারে.রেডুস ব্যবহার করে আমাকে সঠিক পথে পৌঁছেছে।

যাইহোক, আসলে একের পর এক মৃত্যুদন্ডের প্রতিশ্রুতি ফিরিয়ে ফাংশনগুলি পেতে আমাকে আরও কিছু বাসা বাঁধতে হয়েছিল।

আমার আসল ব্যবহারের ক্ষেত্রগুলি এমন ফাইলগুলির একটি অ্যারে যা স্রোতের সীমাবদ্ধতার কারণে আমাকে একের পর এক ক্রম স্থানান্তর করতে হবে ...

এখানেই আমি শেষ করেছি।

getAllFiles().then( (files) => {
    return files.reduce((p, theFile) => {
        return p.then(() => {
            return transferFile(theFile); //function returns a promise
        });
    }, Promise.resolve()).then(()=>{
        console.log("All files transferred");
    });
}).catch((error)=>{
    console.log(error);
});

পূর্ববর্তী উত্তরগুলির মতো, ব্যবহার করে:

getAllFiles().then( (files) => {
    return files.reduce((p, theFile) => {
        return p.then(transferFile(theFile));
    }, Promise.resolve()).then(()=>{
        console.log("All files transferred");
    });
}).catch((error)=>{
    console.log(error);
});

অন্যটি শুরু করার আগে স্থানান্তরটি সম্পূর্ণ হওয়ার জন্য অপেক্ষা করেননি এবং প্রথম ফাইল স্থানান্তর শুরু হওয়ার আগেই "সমস্ত ফাইল স্থানান্তরিত" পাঠ্য এসেছে।

আমি কী ভুল করেছি তা নিশ্চিত নন, তবে আমার জন্য কী কাজ করেছে তা ভাগ করে নিতে চেয়েছিলেন।

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


4

কেবল @ বার্গির উত্তরটি বিশদভাবে জানাতে (যা খুব সংক্ষিপ্ত, তবে বোঝার পক্ষে জটিল);

এই কোড অ্যারেতে প্রতিটি আইটেম চালাবে এবং পরবর্তীটিতে 'পরে চেইন' যুক্ত করবে;

function eachorder(prev,order) {
        return prev.then(function() {
          return get_order(order)
            .then(check_order)
            .then(update_order);
        });
    }
orderArray.reduce(eachorder,Promise.resolve());

আশা করি তা বোধগম্য হয়।


3

আপনি পুনরাবৃত্তি ফাংশন ব্যবহার করে একটি অ্যাসিঙ্ক ফাংশন দিয়ে ক্রমান্বয়ে পুনরাবৃত্তিযোগ্য প্রক্রিয়া করতে পারেন। উদাহরণস্বরূপ, aঅ্যাসিনক্রোনাস ফাংশন দিয়ে প্রক্রিয়া করার জন্য একটি অ্যারে দেওয়া হয়েছে someAsyncFunction():

var a = [1, 2, 3, 4, 5, 6]

function someAsyncFunction(n) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("someAsyncFunction: ", n)
      resolve(n)
    }, Math.random() * 1500)
  })
}

//You can run each array sequentially with: 

function sequential(arr, index = 0) {
  if (index >= arr.length) return Promise.resolve()
  return someAsyncFunction(arr[index])
    .then(r => {
      console.log("got value: ", r)
      return sequential(arr, index + 1)
    })
}

sequential(a).then(() => console.log("done"))


array.prototype.reduceপুনরাবৃত্তির ক্রিয়াকলাপের চেয়ে পারফরম্যান্সের ক্ষেত্রে ব্যবহার করা অনেক বেশি ভাল
ম্যাটিউজ সোইয়স্কি

@ ম্যাটিউজসোভিস্কি, প্রতিটি কলের মধ্যে একটি 1500 মিমি টাইমআউট হয়। এটি ক্রমান্বয়ে async কল করছে তা বিবেচনা করে, খুব তাড়াতাড়ি অ্যাসিঙ্ক টার্নআরাউন্ডের জন্যও এটি কীভাবে প্রাসঙ্গিক তা দেখতে শক্ত hard
মার্ক মেয়ার

ধরা যাক আপনাকে একে অপরের পরে 40 টি সত্যই দ্রুত অ্যাসিঙ্ক ফাংশন সম্পাদন করতে হবে - পুনরাবৃত্ত ফাংশনগুলি ব্যবহার করা আপনার স্মৃতিটিকে দ্রুত দ্রুত
আটকে রাখবে

@ ম্যাটিউজসোভিস্কি, যে স্ট্যাকটি এখানে বাজছে না ... আমরা প্রতিটি কলের পরে ফিরে আসছি। আপনি reduceযেখানে then()এক ধাপে পুরো চেইন তৈরি করতে হবে তার সাথে তার তুলনা করুন এবং তারপরে কার্যকর করুন।
মার্ক মেয়ার

সিক্যুয়াল ফাংশনটির 40 তম কলটিতে ক্রিয়াকলাপের প্রথম কলটি স্মৃতিতে এখনও অনুক্রমিক ক্রিয়াকলাপগুলির শৃঙ্খলার প্রত্যাবর্তনের জন্য অপেক্ষা করছে
চেনটি অপেক্ষায় ম্যাটিউজ সোভিস্কি

2

অ্যাসিঙ্ক ব্যবহার করে একটি প্রতিশ্রুতির অ্যারের অপেক্ষায় সহজেই ক্রমানুসারে সম্পাদন করা যায়:

let a = [promise1, promise2, promise3];

async function func() {
  for(let i=0; i<a.length; i++){
    await a[i]();
  }  
}

func();

দ্রষ্টব্য: উপরোক্ত বাস্তবায়নে, যদি কোন প্রতিশ্রুতি প্রত্যাখাত হয় তবে বাকীগুলি কার্যকর করা হবে না you আপনি যদি সমস্ত প্রতিশ্রুতি কার্যকর করতে চান তবে আপনার await a[i]();ভিতরে আবরণ করুনtry catch


2

সমান্তরাল

এই উদাহরণ দেখুন

const resolveAfterTimeout = async i => {
  return new Promise(resolve => {
    console.log("CALLED");
    setTimeout(() => {
      resolve("RESOLVED", i);
    }, 5000);
  });
};

const call = async () => {
  const res = await Promise.all([
    resolveAfterTimeout(1),
    resolveAfterTimeout(2),
    resolveAfterTimeout(3),
    resolveAfterTimeout(4),
    resolveAfterTimeout(5),
    resolveAfterTimeout(6)
  ]);
  console.log({ res });
};

call();

কোডটি চালিয়ে এটি ছয়টি প্রতিশ্রুতির জন্য "কল" কনসোল করবে এবং যখন তারা সমাধান হয়ে যাবে তখন একই সময়ে সময়সীমা শেষ হওয়ার পরে প্রতি 6 টি প্রতিক্রিয়া কনসোল করবে


2

নোডজেএস সমান্তরালে প্রতিশ্রুতিগুলি চালায় না, এটি একই সাথে চালায় কারণ এটি একক থ্রেডেড ইভেন্ট লুপ আর্কিটেকচার। একাধিক কোর সিপিইউর সুবিধা নেওয়ার জন্য একটি নতুন শিশু প্রক্রিয়া তৈরি করে জিনিসগুলিকে সমান্তরালে চালানোর সম্ভাবনা রয়েছে।

সমান্তরাল বনাম কনক্যুরেন্ট

আসলে, কি Promise.all হল, প্রতিশ্রুতিগুলি যথাযথ কাতারে স্ট্যাক করা (ইভেন্ট লুপ আর্কিটেকচার দেখুন) সেগুলি একযোগে চালনা করা (পি 1, পি 2, ... কল করুন) তারপরে প্রতিটি ফলাফলের জন্য অপেক্ষা করুন, তারপরে প্রতিশ্রুতিটি সমাধান করুন সমস্ত প্রতিশ্রুতি দিয়ে ফলাফল নেই। প্রতিশ্রুতি। সমস্ত প্রথম প্রতিশ্রুতিতে ব্যর্থ হবে যা ব্যর্থ হয়, যদি না আপনি নিজেই প্রত্যাখ্যান পরিচালনা করেন।

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

অবশেষে, আপনার প্রশ্নের উত্তর দেওয়ার জন্য, Promise.allসমান্তরাল বা ক্রমানুসারে নয় তবে একই সাথে কার্যকর করা হবে না।


এটা সঠিক না. নোডজেএস সমান্তরালভাবে জিনিস চালাতে পারে। নোডজেএস কর্মী থ্রেড একটি ধারণা আছে। ডিফল্টরূপে কর্মী থ্রেডের সংখ্যা 4 For উদাহরণস্বরূপ, আপনি যদি দুটি মান হ্যাশ করতে ক্রিপ্টো লাইব্রেরি ব্যবহার করেন তবে আপনি সেগুলি সমান্তরালে কার্যকর করতে পারেন। দুটি কর্মী থ্রেড কাজটি পরিচালনা করবে। অবশ্যই, আপনার সিপিইউতে সমান্তরালতা সমর্থন করতে মাল্টি-কোর হতে হবে।
শিহাব

হ্যাঁ, আপনি ঠিক বলেছেন, প্রথম অনুচ্ছেদের শেষে আমি যা বলেছিলাম, তবে আমি শিশু প্রক্রিয়া সম্পর্কে কথা বলেছিলাম, অবশ্যই তারা শ্রমিক চালাতে পারে।
এড্রিয়েন দে পেরেটি

1

বার্গির উত্তরটি আমাকে কলকে সিঙ্ক্রোনাস করতে সহায়তা করেছে I আমি নীচে একটি উদাহরণ যুক্ত করেছি যেখানে আমরা পূর্ববর্তী ফাংশনটি বলার পরে প্রতিটি ফাংশন ডাকি।

function func1 (param1) {
    console.log("function1 : " + param1);
}
function func2 () {
    console.log("function2");
}
function func3 (param2, param3) {
    console.log("function3 : " + param2 + ", " + param3);
}

function func4 (param4) {
    console.log("function4 : " + param4);
}
param4 = "Kate";

//adding 3 functions to array

a=[
    ()=>func1("Hi"),
    ()=>func2(),
    ()=>func3("Lindsay",param4)
  ];

//adding 4th function

a.push(()=>func4("dad"));

//below does func1().then(func2).then(func3).then(func4)

a.reduce((p, fn) => p.then(fn), Promise.resolve());

এটি কি মূল প্রশ্নের উত্তর?
জিউলিও ক্যাকসিন

0

আপনি লুপ জন্য এটি করতে পারেন।

async ফাংশন রিটার্ন প্রতিশ্রুতি

async function createClient(client) {
    return await Client.create(client);
}

let clients = [client1, client2, client3];

আপনি যদি নিম্নলিখিত কোডগুলি লিখেন তবে ক্লায়েন্ট সমান্তরালভাবে তৈরি করা হবে

const createdClientsArray = yield Promise.all(clients.map((client) =>
    createClient(client);
));

তারপরে সমস্ত ক্লায়েন্ট সমান্তরালভাবে তৈরি করা হয়। তবে আপনি যদি ক্রমানুসারে ক্লায়েন্ট তৈরি করতে চান তবে আপনার লুপের জন্য ব্যবহার করা উচিত

const createdClientsArray = [];
for(let i = 0; i < clients.length; i++) {
    const createdClient = yield createClient(clients[i]);
    createdClientsArray.push(createdClient);
}

তারপরে সমস্ত ক্লায়েন্ট ক্রমান্বয়ে তৈরি করা হয়।

শুভ কোডিং :)


8
এই মুহুর্তে, async/ awaitকেবলমাত্র একটি ট্রান্সপ্লেলার সহ, বা নোড ব্যতীত অন্যান্য ইঞ্জিন ব্যবহার করে । এছাড়াও, আপনার সত্যিকারের asyncসাথে মিশ্রিত হওয়া উচিত নয় yield। ট্রান্সপ্লেলার দিয়ে তারা একইভাবে কাজ করে এবং coতারা সত্যই একেবারে আলাদা এবং একে অপরকে সাধারণভাবে নীচু করে না। এছাড়াও, আপনার এই বিধিনিষেধগুলি উল্লেখ করা উচিত কারণ আপনার উত্তরটি নবাগত প্রোগ্রামারগুলিকে বিভ্রান্ত করছে।
ইয়ানিক রচন

0

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

async function run() {
    for (let val of arr) {
        const res = await someQuery(val)
        console.log(val)
    }
}

run().then().catch()

0

এটি আপনার প্রশ্নের অংশের উত্তর দিতে পারে।

হ্যাঁ, আপনি নীচে নীচে প্রতিশ্রুতি ফাংশনগুলির একটি অ্যারে চেইন করতে পারেন ... (এটি প্রতিটি ফাংশনের ফলাফলটিকে পরের দিকে পাস করে)। আপনি অবশ্যই প্রতিটি ফাংশনে একই যুক্তি (বা কোনও যুক্তি) পাস করার জন্য এটি সম্পাদনা করতে পারেন।

function tester1(a) {
  return new Promise(function(done) {
    setTimeout(function() {
      done(a + 1);
    }, 1000);
  })
}

function tester2(a) {
  return new Promise(function(done) {
    setTimeout(function() {
      done(a * 5);
    }, 1000);
  })
}

function promise_chain(args, list, results) {

  return new Promise(function(done, errs) {
    var fn = list.shift();
    if (results === undefined) results = [];
    if (typeof fn === 'function') {
      fn(args).then(function(result) {
        results.push(result);
        console.log(result);
        promise_chain(result, list, results).then(done);
      }, errs);
    } else {
      done(results);
    }

  });

}

promise_chain(0, [tester1, tester2, tester1, tester2, tester2]).then(console.log.bind(console), console.error.bind(console));


0

নোডজেএস-এ সমস্যা সমাধানের চেষ্টা করার সময় আমি এই পৃষ্ঠাটি জুড়ে হোঁচট খেয়েছি: ফাইল খণ্ডগুলি পুনরায় অপ্রয়োজনীয়। মূলত: আমার কাছে ফাইলের একটি অ্যারে রয়েছে। একটি বড় ফাইল তৈরি করার জন্য আমাকে সঠিক ক্রমে এই সমস্ত ফাইল যুক্ত করতে হবে। আমাকে অবশ্যই এটি অবিচ্ছিন্নভাবে করতে হবে।

নোডের 'fs' মডিউলটি অ্যাপেন্ডফাইসাইক সরবরাহ করে তবে আমি এই অপারেশনের সময় সার্ভারটি ব্লক করতে চাইনি। আমি fs.promises মডিউলটি ব্যবহার করতে এবং এই জিনিসগুলি একসাথে শৃঙ্খলে নেওয়ার একটি উপায় খুঁজে পেতে চেয়েছিলাম। এই পৃষ্ঠার উদাহরণগুলি আমার পক্ষে বেশ কার্যকর হয়নি কারণ আমার আসলে দুটি অপারেশন প্রয়োজন: fsPromises.read () ফাইল খণ্ডে পড়ার জন্য এবং fsPromises.appendFile () গন্তব্য ফাইলটিতে কনক্যাট করার জন্য। আমি জাভাস্ক্রিপ্টের সাথে আরও ভাল থাকলে আমি আগের উত্তরগুলি আমার পক্ষে কাজ করতে পারতাম। ;-)

আমি এইজন্য হোঁচট খেয়েছি ... https://css-tricks.com/why-using-reduce-to-sequentially-resolve-promises-works/ using-reduce-to-sequentially-resolve-promises- ... এবং আমি একসাথে একটি কার্যক্ষম সমাধান হ্যাক করতে সক্ষম হয়েছি।

TLDR:

/**
 * sequentially append a list of files into a specified destination file
 */
exports.append_files = function (destinationFile, arrayOfFilenames) {
    return arrayOfFilenames.reduce((previousPromise, currentFile) => {
        return previousPromise.then(() => {
            return fsPromises.readFile(currentFile).then(fileContents => {
                return fsPromises.appendFile(destinationFile, fileContents);
            });
        });
    }, Promise.resolve());
};

এবং এটির জন্য এখানে জুঁই ইউনিট পরীক্ষা:

const fsPromises = require('fs').promises;
const fsUtils = require( ... );
const TEMPDIR = 'temp';

describe("test append_files", function() {
    it('append_files should work', async function(done) {
        try {
            // setup: create some files
            await fsPromises.mkdir(TEMPDIR);
            await fsPromises.writeFile(path.join(TEMPDIR, '1'), 'one');
            await fsPromises.writeFile(path.join(TEMPDIR, '2'), 'two');
            await fsPromises.writeFile(path.join(TEMPDIR, '3'), 'three');
            await fsPromises.writeFile(path.join(TEMPDIR, '4'), 'four');
            await fsPromises.writeFile(path.join(TEMPDIR, '5'), 'five');

            const filenameArray = [];
            for (var i=1; i < 6; i++) {
                filenameArray.push(path.join(TEMPDIR, i.toString()));
            }

            const DESTFILE = path.join(TEMPDIR, 'final');
            await fsUtils.append_files(DESTFILE, filenameArray);

            // confirm "final" file exists    
            const fsStat = await fsPromises.stat(DESTFILE);
            expect(fsStat.isFile()).toBeTruthy();

            // confirm content of the "final" file
            const expectedContent = new Buffer('onetwothreefourfive', 'utf8');
            var fileContents = await fsPromises.readFile(DESTFILE);
            expect(fileContents).toEqual(expectedContent);

            done();
        }
        catch (err) {
            fail(err);
        }
        finally {
        }
    });
});

আমি আশা করি এটি কাউকে সাহায্য করবে

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