প্রতিটি লুপের সাথে অ্যাসিঙ্ক / অপেক্ষা করুন /


1127

সেখানে ব্যবহার করে কোনো সমস্যা হয় async/ awaitএকটি forEachলুপ? আমি ফাইলগুলির একটি অ্যারের মাধ্যমে এবং awaitপ্রতিটি ফাইলের সামগ্রীতে লুপ করার চেষ্টা করছি ।

import fs from 'fs-promise'

async function printFiles () {
  const files = await getFilePaths() // Assume this works fine

  files.forEach(async (file) => {
    const contents = await fs.readFile(file, 'utf8')
    console.log(contents)
  })
}

printFiles()

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

উত্তর:


2142

অবশ্যই কোডটি কাজ করে তবে অবশ্যই আমি নিশ্চিত যে এটি আপনি যা করবেন আশা করে তা তা করে না। এটি কেবল একাধিক অ্যাসিনক্রোনাস কল বন্ধ printFilesকরে দেয় , তবে ফাংশনটি তার পরে তাৎক্ষণিকভাবে ফিরে আসে।

ক্রমানুসারে পড়া হচ্ছে

আপনি যদি ক্রমানুসারে ফাইলগুলি পড়তে চান তবে আপনি প্রকৃতপক্ষে ব্যবহার করতে পারবেন নাforEachfor … ofপরিবর্তে কেবল একটি আধুনিক লুপ ব্যবহার করুন, এতে awaitপ্রত্যাশার মতো কাজ করবে:

async function printFiles () {
  const files = await getFilePaths();

  for (const file of files) {
    const contents = await fs.readFile(file, 'utf8');
    console.log(contents);
  }
}

সমান্তরালে পড়া

আপনি যদি সমান্তরালভাবে ফাইলগুলি পড়তে চান তবে আপনি প্রকৃতপক্ষে ব্যবহার করতে পারবেন নাforEach । প্রতিটি asyncকলব্যাক ফাংশন কল একটি প্রতিশ্রুতি দেয় না, তবে আপনি তাদের অপেক্ষা না করে এড়িয়ে চলে যাচ্ছেন। কেবল mapপরিবর্তে ব্যবহার করুন, এবং আপনি যে প্রতিশ্রুতিগুলি পাবেন তা সন্ধানের জন্য অপেক্ষা করতে পারেন Promise.all:

async function printFiles () {
  const files = await getFilePaths();

  await Promise.all(files.map(async (file) => {
    const contents = await fs.readFile(file, 'utf8')
    console.log(contents)
  }));
}

33
আপনি দয়া করে ব্যাখ্যা করতে পারেন কেন for ... of ...কাজ করে?
ডেমোনবেন

84
ঠিক আছে আমি জানি কেন ... বাবেল ব্যবহারের ফলে async/ awaitজেনারেটরের ক্রিয়ায় রূপান্তর হবে এবং ব্যবহারের forEachঅর্থ প্রতিটি পুনরুক্তির একটি পৃথক জেনারেটর ফাংশন রয়েছে যার অন্যগুলির সাথে কোনও সম্পর্ক নেই। সুতরাং এগুলি স্বাধীনভাবে কার্যকর করা হবে এবং next()অন্যের সাথে তার কোনও প্রসঙ্গ নেই । প্রকৃতপক্ষে, একটি সাধারণ for()লুপটিও কাজ করে কারণ পুনরাবৃত্তিগুলি একটি একক জেনারেটরের ফাংশনেও রয়েছে।
ডেমোনবেন

21
@ ডেমেনবনে: সংক্ষেপে, এটি কাজ করার জন্য ডিজাইন করা হয়েছিল :-) সমস্ত নিয়ন্ত্রণ কাঠামো সহ awaitবর্তমান ফাংশন মূল্যায়ন স্থগিত করে । হ্যাঁ, এটি সম্পর্কিত জেনারেটরের সাথে একেবারে অনুরূপ (যে কারণে তারা পলিফিল async / অপেক্ষা করতে ব্যবহৃত হয়)।
বার্গি

3
@ আরভ0 আসলে নয়, একটি asyncফাংশন Promiseএক্সিকিউটার কলব্যাকের থেকে একেবারেই আলাদা , তবে হ্যাঁ mapকলব্যাক উভয় ক্ষেত্রেই একটি প্রতিশ্রুতি দেয়।
বার্গি

5
আপনি যখন জেএস প্রতিশ্রুতি সম্পর্কে জানতে আসবেন, তবে পরিবর্তে লাতিন অনুবাদ করে আধ ঘন্টা ব্যবহার করুন। আশা করি আপনি @ বারগি;) গর্বিত
ফ্যালিক্স

187

ES2018 এর সাহায্যে আপনি উপরের সমস্ত উত্তরগুলিকে ব্যাপকভাবে সরল করতে সক্ষম হবেন:

async function printFiles () {
  const files = await getFilePaths()

  for await (const file of fs.readFile(file, 'utf8')) {
    console.log(contents)
  }
}

বৈশিষ্টটি দেখুন: প্রস্তাবনা-অ্যাসিঙ্ক-পুনরাবৃত্তি


2018-09-10: এই উত্তরটি সম্প্রতি বেশ মনোযোগ পাচ্ছে, অ্যাসিঙ্ক্রোনাস পুনরাবৃত্তি সম্পর্কে আরও তথ্যের জন্য দয়া করে অ্যাক্সেল রাউশমায়ারের ব্লগ পোস্টটি দেখুন: ES2018: অ্যাসিনক্রোনাস পুনরাবৃত্তি


4
আপভোটেড, অ্যাসিঙ্ক পুনরাবৃত্তি সম্পর্কে আরও কিছু জানতে চাইলে যে কেউ যদি আপনার উত্তরটিতে সেই নির্দিষ্ট লিঙ্কটি রাখতে পারেন তবে দুর্দান্ত ।
সাদাক

8
এটি পুনরুক্তিতে ফাইলের পরিবর্তে সামগ্রী থাকা উচিত নয়
ফ্লাফিবিং

10
লোকেরা কেন এই উত্তরটিকে সমর্থন করে? উত্তর, প্রশ্ন এবং প্রস্তাবটি নিবিড়ভাবে দেখুন। এর পরে ofঅ্যাসিঙ্ক ফাংশন হওয়া উচিত যা একটি অ্যারে ফিরিয়ে দেবে। এটি কাজ করে না এবং ফ্রান্সিসকো বলেছিল;
ইয়েভেনিই হেরাসিমচুক

3
সম্পূর্ণরূপে @AntonioVal এর সাথে একমত হন। এটি কোনও উত্তর নয়।
ইয়েভেনিই হেরাসিমচুক

2
যদিও আমি সম্মত হলাম এটি কোনও উত্তর নয়, কোনও প্রস্তাব উত্থাপন করা এর জনপ্রিয়তা বাড়ানোর উপায় যা সম্ভবত এটি পরে ব্যবহার করার আগে এটি উপলব্ধ করা সম্ভব।
রবার্ট মোলিনা

61

এর পরিবর্তে (যা সমাধান করা হয় তার Promise.allক্রয়ের Array.prototype.mapগ্যারান্টি দেয় না Promise), আমি Array.prototype.reduceএকটি সমাধান দিয়ে শুরু করে Promise:

async function printFiles () {
  const files = await getFilePaths();

  await files.reduce(async (promise, file) => {
    // This line will wait for the last async function to finish.
    // The first iteration uses an already resolved Promise
    // so, it will immediately continue.
    await promise;
    const contents = await fs.readFile(file, 'utf8');
    console.log(contents);
  }, Promise.resolve());
}

1
এটি নিখুঁতভাবে কাজ করে, আপনাকে অনেক ধন্যবাদ। আপনি এখানে কি ঘটছে তা ব্যাখ্যা করতে পারেন Promise.resolve()এবং await promise;?
parrker9

1
এটি বেশ দুর্দান্ত। আমি কি এই ভেবে ঠিক আছি যে ফাইলগুলি একবারে একবারে পাঠানো হবে না?
গলিজেয়ার

1
@ parrker9 Promise.resolve()একটি ইতিমধ্যে সমাধান করা Promiseবস্তুটি ফেরত দেয় , যাতে reduceএটির একটি Promiseশুরু করা উচিত। শৃঙ্খলে await promise;সমাধানের জন্য শেষের জন্য অপেক্ষা করবে Promise। @ গলিজার এই ফাইলগুলি ক্রমান্বয়ে প্রক্রিয়া করা হবে, একবারে একটি করে।
টিমোথি জর্ন

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

1
@ শায়, আপনার অর্থ ক্রমিক, নয় সিনক্রোনাস। এটি এখনও অবিচ্ছিন্ন - অন্য জিনিসগুলি নির্ধারিত থাকলে এগুলি এখানে পুনরাবৃত্তির মধ্যে চলে যাবে।
টিমোথি জর্ন

32

P-পুনরাবৃত্তির npm কার্যকরী এরে পুনরাবৃত্তির পদ্ধতি যাতে তারা ASYNC / অপেক্ষায় রয়েছেন নিয়ে খুব সহজবোধ্য ভাবে ব্যবহার করা যেতে পারে মডিউল।

আপনার ক্ষেত্রে একটি উদাহরণ:

const { forEach } = require('p-iteration');
const fs = require('fs-promise');

(async function printFiles () {
  const files = await getFilePaths();

  await forEach(files, async (file) => {
    const contents = await fs.readFile(file, 'utf8');
    console.log(contents);
  });
})();

1
আমি এটি পছন্দ করি কারণ এটিতে জেএসের মতোই একই কার্যাদি / পদ্ধতি রয়েছে - আমার ক্ষেত্রে আমার someচেয়ে বরং প্রয়োজন forEach। ধন্যবাদ!
মাইকমেকানা

25

এখানে কিছু forEachAsyncপ্রোটোটাইপ রয়েছে। আপনি awaitতাদের প্রয়োজন নোট :

Array.prototype.forEachAsync = async function (fn) {
    for (let t of this) { await fn(t) }
}

Array.prototype.forEachAsyncParallel = async function (fn) {
    await Promise.all(this.map(fn));
}

দ্রষ্টব্য আপনি নিজের কোডে এটি অন্তর্ভুক্ত করার সময়, অন্যের কাছে বিতরণ করা লাইব্রেরিতে এগুলি অন্তর্ভুক্ত করা উচিত নয় (তাদের গ্লোবালগুলি দূষিত করা এড়াতে)।


1
যদিও আমি প্রোটোটাইপগুলিতে সরাসরি জিনিসগুলি যুক্ত করতে দ্বিধা বোধ করি, তবে এটি প্রতিটি বাস্তবায়নের জন্য একটি দুর্দান্ত অ্যাসিঙ্ক
ড্যানিয়েশন

2
নামটি যতক্ষণ ভবিষ্যতে অনন্য (যতক্ষণ না আমি ব্যবহার করব _forEachAsync) এটি যুক্তিসঙ্গত। আমি এটিও মনে করি এটি সর্বোত্তম উত্তর কারণ এটি প্রচুর বয়লারপ্লেট কোড সংরক্ষণ করে।
মাইকমেকানা

1
@estus এটি অন্য মানুষের কোড দূষণ এড়ানোর জন্য। কোডটি যদি আমাদের ব্যক্তিগত প্রতিষ্ঠানের অন্তর্ভুক্ত, এবং গ্লোবালগুলি একটি ভালভাবে চিহ্নিত ফাইলে থাকে ( globals.jsভাল হবে) আমরা আমাদের পছন্দ মতো গ্লোবালগুলি যুক্ত করতে পারি।
মাইকম্যাকানা

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

1
@estus শিওর আমি এখানে (বিশেষত উত্পাদনশীল নয়) আলোচনাটি সংরক্ষণ করতে প্রশ্নটিতে একটি সতর্কতা যুক্ত করেছি।
মাইকমেকানা

6

@ বার্গির উত্তর ছাড়াও , আমি তৃতীয় বিকল্পটি দিতে চাই। এটি @ বার্গির ২ য় উদাহরণের মতো, তবে প্রতিটি readFileস্বতন্ত্রভাবে অপেক্ষা করার পরিবর্তে , আপনি প্রতিশ্রুতির একটি অ্যারে তৈরি করেন, যার প্রতিটি শেষে আপনি অপেক্ষা করেন।

import fs from 'fs-promise';
async function printFiles () {
  const files = await getFilePaths();

  const promises = files.map((file) => fs.readFile(file, 'utf8'))

  const contents = await Promise.all(promises)

  contents.forEach(console.log);
}

নোট করুন যে ফাংশনটি পাস হয়েছে .map()তা asyncহওয়ার দরকার নেই , যেহেতু যেভাবে fs.readFileকোনও প্রতিশ্রুতি বস্তুটি দেয়। অতএব promisesপ্রতিশ্রুতিবদ্ধ অবজেক্টগুলির একটি অ্যারে, যা এতে প্রেরণ করা যায়Promise.all()

@ বার্গির উত্তরে কনসোলটি ফাইলের সামগ্রীগুলি পড়ার ক্রমে লগ করতে পারে। উদাহরণস্বরূপ, যদি সত্যিই কোনও ছোট ফাইল যদি কোনও বড় ফাইলের আগে পড়া শেষ করে তবে অ্যারেতে বড় ফাইলের পরে যদি ছোট ফাইল আসে তবে এটি প্রথমে লগ হয় files। তবে উপরের আমার পদ্ধতিতে, আপনি গ্যারান্টিযুক্ত যে কনসোল সরবরাহ করা অ্যারে হিসাবে একই ক্রমে ফাইলগুলি লগ করবে।


1
আমি নিশ্চিত যে আপনি ভুল: আমি নিশ্চিত যে আপনার পদ্ধতিটিও ফাইলগুলি যথাযথভাবে পড়তে পারে। হ্যাঁ, এটি আউটপুটটিকে সঠিক ক্রমে (এর কারণে await Promise.all) লগ ইন করবে , তবে ফাইলগুলি অন্য কোনও ক্রমে পড়ে থাকতে পারে, যা আপনার বিবৃতিটির সাথে বিরোধী "আপনার গ্যারান্টিযুক্ত কনসোল ফাইলগুলিকে একই ক্রমে লগ করবে পড়া "।
ভেন্রিক্স

1
@ ভেনরিক্স আপনি ঠিক বলেছেন, সংশোধনের জন্য ধন্যবাদ। আমি আমার উত্তর আপডেট করেছি।
ছারভে

5

fsপ্রতিশ্রুতি ভিত্তিক যখন বার্গির সমাধান ভাল কাজ করে । আপনি ব্যবহার করতে পারেন bluebird, fs-extraবা fs-promiseএই জন্য।

তবে নোডের স্থানীয় fsলিবারির সমাধান নিম্নরূপ:

const result = await Promise.all(filePaths
    .map( async filePath => {
      const fileContents = await getAssetFromCache(filePath, async function() {

        // 1. Wrap with Promise    
        // 2. Return the result of the Promise
        return await new Promise((res, rej) => {
          fs.readFile(filePath, 'utf8', function(err, data) {
            if (data) {
              res(data);
            }
          });
        });
      });

      return fileContents;
    }));

দ্রষ্টব্য: require('fs') বাধ্যতামূলকভাবে তৃতীয় আর্গুমেন্ট হিসাবে ফাংশন নেয়, অন্যথায় ত্রুটি নিক্ষেপ করে:

TypeError [ERR_INVALID_CALLBACK]: Callback must be a function

4

উভয় সমাধানের কাজ, তবে অ্যান্টোনিও কম কোড নিয়ে কাজ করেছে, এখানে এটি বিভিন্ন ডাটাবেস থেকে আমার বিভিন্ন ডাটাবেস থেকে ডেটা সমাধান করতে সহায়তা করেছে এবং তারপরে সেগুলি একটি অ্যারেতে ঠেলাঠেলি করে এবং পরে সমস্ত প্রতিশ্রুতিতে সমাধান করেছে সম্পন্ন:

Promise.all(PacksList.map((pack)=>{
    return fireBaseRef.child(pack.folderPath).once('value',(snap)=>{
        snap.forEach( childSnap => {
            const file = childSnap.val()
            file.id = childSnap.key;
            allItems.push( file )
        })
    })
})).then(()=>store.dispatch( actions.allMockupItems(allItems)))

3

কোনও ফাইলটিতে এমন কয়েকটি পদ্ধতি পপ করা বেশ বেদনাদায়ক যা সিরিয়ালিকৃত ক্রমে অ্যাসিনক্রোনাস ডেটা পরিচালনা করবে এবং আপনার কোডকে আরও প্রচলিত গন্ধ দেবে। উদাহরণ স্বরূপ:

module.exports = function () {
  var self = this;

  this.each = async (items, fn) => {
    if (items && items.length) {
      await Promise.all(
        items.map(async (item) => {
          await fn(item);
        }));
    }
  };

  this.reduce = async (items, fn, initialValue) => {
    await self.each(
      items, async (item) => {
        initialValue = await fn(initialValue, item);
      });
    return initialValue;
  };
};

এখন, ধরে নিলাম যে এটি './myAsync.js' এ সংরক্ষিত হয়েছে আপনি সংলগ্ন ফাইলটিতে নীচের মতো কিছু করতে পারেন:

...
/* your server setup here */
...
var MyAsync = require('./myAsync');
var Cat = require('./models/Cat');
var Doje = require('./models/Doje');
var example = async () => {
  var myAsync = new MyAsync();
  var doje = await Doje.findOne({ name: 'Doje', noises: [] }).save();
  var cleanParams = [];

  // FOR EACH EXAMPLE
  await myAsync.each(['bork', 'concern', 'heck'], 
    async (elem) => {
      if (elem !== 'heck') {
        await doje.update({ $push: { 'noises': elem }});
      }
    });

  var cat = await Cat.findOne({ name: 'Nyan' });

  // REDUCE EXAMPLE
  var friendsOfNyanCat = await myAsync.reduce(cat.friends,
    async (catArray, friendId) => {
      var friend = await Friend.findById(friendId);
      if (friend.name !== 'Long cat') {
        catArray.push(friend.name);
      }
    }, []);
  // Assuming Long Cat was a friend of Nyan Cat...
  assert(friendsOfNyanCat.length === (cat.friends.length - 1));
}

2
গৌণ সংযোজন, আপনার প্রতীক্ষিত / অ্যাসিঙ্কগুলি আবদ্ধ করতে / ব্লকগুলিতে আবৃত করতে ভুলবেন না !!
জে এডওয়ার্ডস

3

@ বার্গির প্রতিক্রিয়া পছন্দ করুন তবে একটি পার্থক্য সহ।

Promise.all কেউ যদি প্রত্যাখ্যান হয় তবে সমস্ত প্রতিশ্রুতিগুলি প্রত্যাখ্যান করে।

সুতরাং, একটি পুনরাবৃত্তি ব্যবহার করুন।

const readFilesQueue = async (files, index = 0) {
    const contents = await fs.readFile(files[index], 'utf8')
    console.log(contents)

    return files.length <= index
        ? readFilesQueue(files, ++index)
        : files

}

const printFiles async = () => {
    const files = await getFilePaths();
    const printContents = await readFilesQueue(files)

    return printContents
}

printFiles()

পুনশ্চ

readFilesQueueprintFilesপার্শ্ব প্রতিক্রিয়া * প্রবর্তিত কারণ বাইরেconsole.log , এটি উপহাস করা, পরীক্ষা করা এবং গুপ্তচরবৃত্তি করা ভাল, সুতরাং সামগ্রীটি (সিডনোট) ফেরত দেয় এমন ফাংশন রাখা ভাল নয়।

সুতরাং, কোডটি কেবল এ দ্বারা ডিজাইন করা যেতে পারে: তিনটি পৃথক ফাংশন যা "খাঁটি" ** এবং কোনও পার্শ্ব প্রতিক্রিয়া প্রবর্তন করে না, পুরো তালিকাটি প্রক্রিয়া করে এবং ব্যর্থ কেসগুলি পরিচালনা করতে সহজেই সংশোধন করা যায়।

const files = await getFilesPath()

const printFile = async (file) => {
    const content = await fs.readFile(file, 'utf8')
    console.log(content)
}

const readFiles = async = (files, index = 0) => {
    await printFile(files[index])

    return files.lengh <= index
        ? readFiles(files, ++index)
        : files
}

readFiles(files)

ভবিষ্যতের সম্পাদনা / বর্তমান অবস্থা

নোড শীর্ষ স্তরের অপেক্ষার সমর্থন করে (এটিতে এখনও একটি প্লাগইন নেই, সম্প্রীতির পতাকাগুলির মাধ্যমে এটি সক্ষম হবে না) এটি দুর্দান্ত তবে একটি সমস্যা সমাধান করে না (কৌশলগতভাবে আমি কেবলমাত্র এলটিএস সংস্করণে কাজ করি)। ফাইলগুলি কীভাবে পাবেন?

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

// more complex version with IIFE to a single module
(async (files) => readFiles(await files())(getFilesPath)

দ্রষ্টব্য যে শব্দার্থক কারণে পরিবর্তনশীল নাম পরিবর্তন। আপনি একটি ফান্টর পাস (একটি ফাংশন যা অন্য ফাংশন দ্বারা আহ্বান করা যেতে পারে) এবং মেমোরিতে একটি পয়েন্টার গ্রহণ করে যা অ্যাপ্লিকেশনটির লজিকের প্রাথমিক ব্লক ধারণ করে।

তবে, যদি মডিউল না হয় এবং আপনার যুক্তিটি রফতানি করা দরকার?

অ্যাসিঙ্ক ফাংশনে ফাংশনগুলি মোড়ানো করুন।

export const readFilesQueue = async () => {
    // ... to code goes here
}

অথবা ভেরিয়েবলের নাম পরিবর্তন করুন, যাই হোক না কেন ...


* পার্শ্ব প্রতিক্রিয়া দ্বারা অ্যাপ্লিকেশনের কোনও প্রচ্ছন্ন প্রভাব মেনান করে যা আইও-র মতো অ্যাপ্লিকেশনটিতে স্ট্যাট্যাট / আচরণ বা ইন্ট্রোস বাগ পরিবর্তন করতে পারে।

** "খাঁটি" দ্বারা, এটি অ্যাস্টোড্রোফে রয়েছে যেহেতু কার্যগুলি শুদ্ধ নয় এবং কোডটি খাঁটি সংস্করণে রূপান্তর করা যায়, যখন কোনও কনসোল আউটপুট না থাকে, কেবল ডেটা ম্যানিপুলেশন থাকে।

এটিকে বাদ দিয়ে, খাঁটি হওয়ার জন্য, আপনাকে এমন মনাদগুলির সাথে কাজ করতে হবে যা পার্শ্ব প্রতিক্রিয়া পরিচালনা করে, এটি ত্রুটি প্রবণ এবং অ্যাপলিকেশনের পৃথকভাবে সেই ত্রুটিটি আচরণ করে।


2

একটি গুরুত্বপূর্ণ সতর্কতা হ'ল: await + for .. ofপদ্ধতি এবং উপায়টিforEach + async আসলে আলাদা আলাদা প্রভাব ফেলে।

awaitএকটি আসল forলুপের ভিতরে থাকা নিশ্চিত করবে যে সমস্ত অ্যাসিঙ্ক কলগুলি একে একে সম্পাদিত হয়েছিল। এবং forEach + asyncউপায় একই সাথে সমস্ত প্রতিশ্রুতিগুলি বন্ধ করে দেবে, যা দ্রুত কিন্তু কখনও কখনও অভিভূত হয় ( যদি আপনি কিছু ডিবি কোয়েরি করেন বা ভলিউম সীমাবদ্ধতার সাথে কিছু ওয়েব পরিষেবাদিতে যান তবে এবং 100,000 কল চালনা করতে চান না)।

আপনি reduce + promiseযদি না ব্যবহার করেন async/awaitএবং নিশ্চিত হন যে ফাইলগুলি একের পর এক পড়ছে তা আপনিও ব্যবহার করতে পারেন (কম মার্জিত) ।

files.reduce((lastPromise, file) => 
 lastPromise.then(() => 
   fs.readFile(file, 'utf8')
 ), Promise.resolve()
)

অথবা আপনি সাহায্যের জন্য একটি ফটোগ্যাস তৈরি করতে পারেন তবে মূলত লুপ অন্তর্নিহিত জন্য একই ব্যবহার করুন।

Array.prototype.forEachAsync = async function(cb){
    for(let x of this){
        await cb(x);
    }
}

কটাক্ষপাত আছে কিভাবে Array.prototype এবং হল Object.prototype জাভাস্ক্রিপ্ট পদ্ধতি নির্ধারণ করতে যাতে এটি লুপ জন্য প্রদর্শিত হবে না । এছাড়াও আপনার সম্ভবত নেটিভ হিসাবে একই পুনরাবৃত্তিটি ব্যবহার করা উচিত forEach- পুনরাবৃত্তির উপর নির্ভর করার পরিবর্তে সূচকগুলি অ্যাক্সেস করা - এবং সূচিটি কলব্যাকটিতে পাস করুন।
বার্গি

আপনি Array.prototype.reduceএমনভাবে ব্যবহার করতে পারেন যা একটি অ্যাসিঙ্ক ফাংশন ব্যবহার করে। আমি আমার উত্তরে একটি উদাহরণ দেখিয়েছি: stackoverflow.com/a/49499491/2537258
টিমোথি জর্ন

2

টাস্ক, ফিউচারাইজ এবং একটি ট্র্যাভারেবলের তালিকা ব্যবহার করে আপনি কেবল তা করতে পারেন

async function printFiles() {
  const files = await getFiles();

  List(files).traverse( Task.of, f => readFile( f, 'utf-8'))
    .fork( console.error, console.log)
}

আপনি কীভাবে এটি সেট আপ করবেন তা এখানে

import fs from 'fs';
import { futurize } from 'futurize';
import Task from 'data.task';
import { List } from 'immutable-ext';

const future = futurizeP(Task)
const readFile = future(fs.readFile)

পছন্দসই কোডটি কাঠামোগত করার আরেকটি উপায় হ'ল

const printFiles = files => 
  List(files).traverse( Task.of, fn => readFile( fn, 'utf-8'))
    .fork( console.error, console.log)

অথবা সম্ভবত আরও কার্যকরী ভিত্তিক

// 90% of encodings are utf-8, making that use case super easy is prudent

// handy-library.js
export const readFile = f =>
  future(fs.readFile)( f, 'utf-8' )

export const arrayToTaskList = list => taskFn => 
  List(files).traverse( Task.of, taskFn ) 

export const readFiles = files =>
  arrayToTaskList( files, readFile )

export const printFiles = files => 
  readFiles(files).fork( console.error, console.log)

তারপরে প্যারেন্ট ফাংশন থেকে

async function main() {
  /* awesome code with side-effects before */
  printFiles( await getFiles() );
  /* awesome code with side-effects after */
}

আপনি যদি সত্যই এনকোডিংয়ে আরও নমনীয়তা চান, আপনি কেবল এটি করতে পারেন (মজা করার জন্য, আমি প্রস্তাবিত পাইপ ফরোয়ার্ড অপারেটরটি ব্যবহার করছি )

import { curry, flip } from 'ramda'

export const readFile = fs.readFile 
  |> future,
  |> curry,
  |> flip

export const readFileUtf8 = readFile('utf-8')

পিএস - আমি কনসোলে এই কোডটি ব্যবহার করে দেখিনি, কিছু টাইপস থাকতে পারে ... "সোজা ফ্রিস্টাইল, গম্বুজের উপরের দিক থেকে!" 90s বাচ্চাদের বলতে হবে। :-p


2

বর্তমানে অ্যারে.ফোর্ প্রতি প্রোটোটাইপ সম্পত্তি অ্যাসিঙ্ক অপারেশনগুলিকে সমর্থন করে না, তবে আমরা আমাদের চাহিদা মেটাতে নিজস্ব পলি-ফিল তৈরি করতে পারি।

// Example of asyncForEach Array poly-fill for NodeJs
// file: asyncForEach.js
// Define asynForEach function 
async function asyncForEach(iteratorFunction){
  let indexer = 0
  for(let data of this){
    await iteratorFunction(data, indexer)
    indexer++
  }
}
// Append it as an Array prototype property
Array.prototype.asyncForEach = asyncForEach
module.exports = {Array}

এবং এটাই! অপারেশনের পরে সংজ্ঞায়িত যে কোনও অ্যারেগুলিতে আপনার কাছে এখন এক অ্যাসিঙ্ক ফরইচ পদ্ধতি রয়েছে।

আসুন এটি পরীক্ষা করি ...

// Nodejs style
// file: someOtherFile.js

const readline = require('readline')
Array = require('./asyncForEach').Array
const log = console.log

// Create a stream interface
function createReader(options={prompt: '>'}){
  return readline.createInterface({
    input: process.stdin
    ,output: process.stdout
    ,prompt: options.prompt !== undefined ? options.prompt : '>'
  })
}
// Create a cli stream reader
async function getUserIn(question, options={prompt:'>'}){
  log(question)
  let reader = createReader(options)
  return new Promise((res)=>{
    reader.on('line', (answer)=>{
      process.stdout.cursorTo(0, 0)
      process.stdout.clearScreenDown()
      reader.close()
      res(answer)
    })
  })
}

let questions = [
  `What's your name`
  ,`What's your favorite programming language`
  ,`What's your favorite async function`
]
let responses = {}

async function getResponses(){
// Notice we have to prepend await before calling the async Array function
// in order for it to function as expected
  await questions.asyncForEach(async function(question, index){
    let answer = await getUserIn(question)
    responses[question] = answer
  })
}

async function main(){
  await getResponses()
  log(responses)
}
main()
// Should prompt user for an answer to each question and then 
// log each question and answer as an object to the terminal

আমরা মানচিত্রের মতো অন্যান্য অ্যারে ফাংশনগুলির জন্যও এটি করতে পারি ...

async function asyncMap(iteratorFunction){
  let newMap = []
  let indexer = 0
  for(let data of this){
    newMap[indexer] = await iteratorFunction(data, indexer, this)
    indexer++
  }
  return newMap
}

Array.prototype.asyncMap = asyncMap

... এবং এইভাবে :)

কিছু বিষয় লক্ষণীয়:

  • আপনার পুনরাবৃত্তি ফাংশনটি অবশ্যই একটি অ্যাসিঙ্ক ফাংশন বা প্রতিশ্রুতি হওয়া উচিত
  • পূর্বে তৈরি কোনও অ্যারেতে Array.prototype.<yourAsyncFunc> = <yourAsyncFunc>এই বৈশিষ্ট্যটি উপলব্ধ থাকবে না

2

কেবল আসল উত্তরে যুক্ত করা হচ্ছে

  • মূল উত্তরে সমান্তরাল পাঠ্য বাক্য গঠন মাঝে মাঝে বিভ্রান্তিকর এবং পড়তে অসুবিধাজনক হতে পারে, সম্ভবত আমরা এটিকে অন্য পদ্ধতিতে লিখতে পারি
async function printFiles() {
  const files = await getFilePaths();
  const fileReadPromises = [];

  const readAndLogFile = async filePath => {
    const contents = await fs.readFile(file, "utf8");
    console.log(contents);
    return contents;
  };

  files.forEach(file => {
    fileReadPromises.push(readAndLogFile(file));
  });

  await Promise.all(fileReadPromises);
}
  • অনুক্রমিক ক্রিয়াকলাপের জন্য, কেবলমাত্র ... এর জন্য নয় , লুপের জন্যও স্বাভাবিক কাজ করবে
async function printFiles() {
  const files = await getFilePaths();

  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    const contents = await fs.readFile(file, "utf8");
    console.log(contents);
  }
}

1

আজ আমি এর একাধিক সমাধান পেয়েছি across ForEach লুপে অ্যাসিঙ্কের প্রতীক্ষিত ফাংশনগুলি চালানো। চারপাশে মোড়ক তৈরি করে আমরা এটি ঘটতে পারি।

এটি কীভাবে অভ্যন্তরীণভাবে কাজ করে তার জন্য, প্রত্যেকটি নেটিভ ফর নেটিভ জন্য এবং কেন এটি একটি এসিঙ্ক ফাংশন কল করতে সক্ষম হয় না এবং বিভিন্ন পদ্ধতির অন্যান্য বিবরণ এখানে লিঙ্কে সরবরাহ করা হয়

এটি করা যায় এমন একাধিক উপায়ে এবং সেগুলি নীচে রয়েছে,

পদ্ধতি 1: মোড়ক ব্যবহার করে।

await (()=>{
     return new Promise((resolve,reject)=>{
       items.forEach(async (item,index)=>{
           try{
               await someAPICall();
           } catch(e) {
              console.log(e)
           }
           count++;
           if(index === items.length-1){
             resolve('Done')
           }
         });
     });
    })();

পদ্ধতি 2: অ্যারে.প্রোটোটাইপের জেনেরিক ফাংশন হিসাবে একই ব্যবহার করা

Array.prototype.forEachAsync.js

if(!Array.prototype.forEachAsync) {
    Array.prototype.forEachAsync = function (fn){
      return new Promise((resolve,reject)=>{
        this.forEach(async(item,index,array)=>{
            await fn(item,index,array);
            if(index === array.length-1){
                resolve('done');
            }
        })
      });
    };
  }

ব্যবহার:

require('./Array.prototype.forEachAsync');

let count = 0;

let hello = async (items) => {

// Method 1 - Using the Array.prototype.forEach 

    await items.forEachAsync(async () => {
         try{
               await someAPICall();
           } catch(e) {
              console.log(e)
           }
        count++;
    });

    console.log("count = " + count);
}

someAPICall = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("done") // or reject('error')
        }, 100);
    })
}

hello(['', '', '', '']); // hello([]) empty array is also be handled by default

পদ্ধতি 3:

প্রতিশ্রুতি

  await Promise.all(items.map(async (item) => {
        await someAPICall();
        count++;
    }));

    console.log("count = " + count);

পদ্ধতি 4: লুপের জন্য প্রচলিত বা লুপের জন্য আধুনিক

// Method 4 - using for loop directly

// 1. Using the modern for(.. in..) loop
   for(item in items){

        await someAPICall();
        count++;
    }

//2. Using the traditional for loop 

    for(let i=0;i<items.length;i++){

        await someAPICall();
        count++;
    }


    console.log("count = " + count);

আপনার 1 এবং 2 পদ্ধতিগুলি কেবলমাত্র ভুল বাস্তবায়ন যেখানে যেখানে Promise.allব্যবহার করা উচিত ছিল - সেগুলি অনেক ধরণের ক্ষেত্রে বিবেচনা করে না।
বার্গি

@ বার্গি: বৈধ মন্তব্যের জন্য ধন্যবাদ, আপনি কি দয়া করে আমাকে 1 এবং 2 পদ্ধতিটি ভুল বলে ব্যাখ্যা করতে পারেন। এটি উদ্দেশ্যটিও পরিবেশন করে। এটি খুব ভাল কাজ করে। এটি বলতে হবে যে এই সমস্ত পদ্ধতিগুলি সম্ভব, পরিস্থিতির উপর নির্ভর করে যে কোনও একটি বেছে নেওয়ার বিষয়ে সিদ্ধান্ত নিতে পারে। আমি একই চলমান উদাহরণ আছে।
প্রণবকান্দ্রো

এটি খালি অ্যারেতে ব্যর্থ হয়, এটি পরিচালনা করতে কোনও ত্রুটি নেই এবং সম্ভবত আরও সমস্যা রয়েছে। চাকা পুনরুদ্ধার করবেন না। শুধু ব্যবহার Promise.all
বার্গি

নির্দিষ্ট পরিস্থিতিতে যেখানে এটি সম্ভব নয় এটি সহায়ক হবে। এছাড়াও ত্রুটি হ্যান্ডলিং ডিফল্টরূপে প্রতিটি এপিআই দ্বারা সম্পন্ন হয় সুতরাং কোনও সমস্যা নেই। এর যত্ন নেওয়া!
প্রণবকান্দ্রো

না, এমন কোনও শর্ত নেই যেখানে Promise.allসম্ভব নয় তবে async/ awaitহয়। এবং না, forEachএকেবারে কোনও প্রতিশ্রুতি ত্রুটি পরিচালনা করে না।
বার্গি

1

এই সমাধানটি মেমোরি-অনুকূলিতও তাই আপনি এটি 10,000 টি ডেটা আইটেম এবং অনুরোধগুলিতে চালাতে পারেন run এখানে অন্যান্য সমাধানগুলির মধ্যে কয়েকটি বড় ডেটা সেটগুলিতে সার্ভার ক্র্যাশ করবে।

টাইপস্ক্রিপ্টে:

export async function asyncForEach<T>(array: Array<T>, callback: (item: T, index: number) => void) {
        for (let index = 0; index < array.length; index++) {
            await callback(array[index], index);
        }
    }

ব্যবহারবিধি?

await asyncForEach(receipts, async (eachItem) => {
    await ...
})

1

আপনি ব্যবহার করতে পারেন Array.prototype.forEach, তবে async / প্রতীক্ষা এতটা উপযুক্ত নয়। এটি কারণ এ্যাসিঙ্ক কলব্যাক থেকে প্রত্যাশিত Array.prototype.forEachপ্রতিশ্রুতি সমাধান হওয়ার প্রত্যাশা করে তবে এর কলব্যাক বাস্তবায়ন থেকে কোনও প্রতিশ্রুতি সমাধান করে না। সুতরাং, আপনি প্রত্যেকের জন্য ব্যবহার করতে পারেন, তবে আপনাকে প্রতিশ্রুতি সমাধানটি নিজেই পরিচালনা করতে হবে।

এখানে প্রতিটি ফাইল ব্যবহার করে সিরিজ ব্যবহার করে মুদ্রণ করা যায় Array.prototype.forEach

async function printFilesInSeries () {
  const files = await getFilePaths()

  let promiseChain = Promise.resolve()
  files.forEach((file) => {
    promiseChain = promiseChain.then(() => {
      fs.readFile(file, 'utf8').then((contents) => {
        console.log(contents)
      })
    })
  })
  await promiseChain
}

Array.prototype.forEachসমান্তরালে ফাইলের বিষয়বস্তু মুদ্রণের জন্য এখানে একটি উপায় (এখনও ব্যবহার করা হচ্ছে )

async function printFilesInParallel () {
  const files = await getFilePaths()

  const promises = []
  files.forEach((file) => {
    promises.push(
      fs.readFile(file, 'utf8').then((contents) => {
        console.log(contents)
      })
    )
  })
  await Promise.all(promises)
}

প্রথম সেনারিও লুপগুলির জন্য আদর্শ যা সিরিয়ায় চালানো দরকার এবং আপনি এটির জন্য ব্যবহার করতে পারবেন না
মার্ক ওডে

0

অ্যান্টোনিও p-iterationভালের মতো , একটি বিকল্প এনপিএম মডিউলটি হ'ল async-af:

const AsyncAF = require('async-af');
const fs = require('fs-promise');

function printFiles() {
  // since AsyncAF accepts promises or non-promises, there's no need to await here
  const files = getFilePaths();

  AsyncAF(files).forEach(async file => {
    const contents = await fs.readFile(file, 'utf8');
    console.log(contents);
  });
}

printFiles();

বিকল্পভাবে, async-afএকটি স্ট্যাটিক পদ্ধতি রয়েছে (লগ / লগএএফএফ) যা প্রতিশ্রুতিগুলির ফলাফলগুলিতে লগ করে:

const AsyncAF = require('async-af');
const fs = require('fs-promise');

function printFiles() {
  const files = getFilePaths();

  AsyncAF(files).forEach(file => {
    AsyncAF.log(fs.readFile(file, 'utf8'));
  });
}

printFiles();

তবে লাইব্রেরির মূল সুবিধাটি হ'ল আপনি এমন কিছু করার জন্য অ্যাসিনক্রোনাস পদ্ধতিগুলি চেইন করতে পারেন:

const aaf = require('async-af');
const fs = require('fs-promise');

const printFiles = () => aaf(getFilePaths())
  .map(file => fs.readFile(file, 'utf8'))
  .forEach(file => aaf.log(file));

printFiles();

async-af


0

কীভাবে এটি ভুল হতে পারে তা দেখতে পদ্ধতির শেষে কনসোল.লগ মুদ্রণ করুন।

যে জিনিসগুলি সাধারণভাবে ভুল হতে পারে:

  • নির্বিচারে আদেশ।
  • মুদ্রণ ফাইলগুলি মুদ্রণের আগে চালানো শেষ করতে পারে।
  • দুর্বল কাজ.

এগুলি সর্বদা ভুল হয় না তবে প্রায়শই স্ট্যান্ডার্ড ব্যবহারের ক্ষেত্রে থাকে।

সাধারণত, forEach ব্যবহারের ফলে ফলাফলটি সর্বশেষ ছাড়া শেষ হয় but এটি ফাংশনের জন্য অপেক্ষা না করে প্রতিটি ফাংশনকে কল করবে যার অর্থ এটি ফাংশন শেষ হওয়ার অপেক্ষা না করেই শেষ করতে সমস্ত ফাংশনকে বলে।

import fs from 'fs-promise'

async function printFiles () {
  const files = (await getFilePaths()).map(file => fs.readFile(file, 'utf8'))

  for(const file of files)
    console.log(await file)
}

printFiles()

এটি নেটিভ জেএসের একটি উদাহরণ যা শৃঙ্খলা রক্ষা করবে, ফাংশনটি অকাল ফেরা থেকে আটকাবে এবং তাত্ত্বিকভাবে সর্বোত্তম কর্মক্ষমতা ধরে রাখবে।

এটা হবে:

  • সমস্ত ফাইলের সমান্তরালে ঘটতে শুরু করে।
  • অপেক্ষা করার প্রতিশ্রুতিতে ফাইলের নাম মানচিত্রের মানচিত্রের মাধ্যমে অর্ডার সংরক্ষণ করুন।
  • অ্যারের দ্বারা সংজ্ঞায়িত ক্রমে প্রতিটি প্রতিশ্রুতির জন্য অপেক্ষা করুন।

এই সমাধানের সাহায্যে প্রথম ফাইলটি অন্যের কাছে প্রথমে উপস্থিত হওয়ার অপেক্ষা না করেই এটি পাওয়া মাত্র তা প্রদর্শিত হবে।

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

এর মূল প্রতিপাদ্য এবং আসল সংস্করণটি হ'ল যদি একাধিক পাঠ একবারে শুরু করা হয় তবে একবারে ঘটতে পারে এমন আরও ত্রুটি থাকার কারণে ত্রুটিগুলি পরিচালনা করা আরও কঠিন।

এমন সংস্করণগুলির সাথে যা একটি সময়ে একটি ফাইল পড়ে এবং তারপরে আর কোনও ফাইল পড়ার চেষ্টা না করে ব্যর্থতায় থামবে। এমনকি একটি বিস্তৃত বাতিলকরণ সিস্টেমের মাধ্যমে এটি প্রথম ফাইলটিতে ব্যর্থ হওয়া তবে ইতিমধ্যে পাশাপাশি অন্যান্য ফাইলগুলির বেশিরভাগটি পড়া এড়ানো কঠিন।

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

সেই উদাহরণটিতে কোনও ত্রুটি নেই। কোনও কিছুর জন্য যদি সেগুলির প্রয়োজন হয় যা হয় সমস্তকে সফলভাবে প্রদর্শিত হয় বা না হয় তবে তা তা করবে না।

গভীরতার সাথে প্রতিটি পর্যায়ে কনসোল.লগ এবং জাল ফাইল রিড সমাধান (পরিবর্তে এলোমেলো দেরি) সহ পরীক্ষার পরামর্শ দেওয়া হয়। যদিও সহজ সমাধানগুলিতে অনেকগুলি সমাধান একই রকম হয় বলে মনে হয় সমস্তর মধ্যে সূক্ষ্ম পার্থক্য রয়েছে যা কেটে ফেলতে কিছু অতিরিক্ত তদন্ত করে।

সমাধানগুলির মধ্যে পার্থক্যটি জানাতে এই মক ব্যবহার করুন:

(async () => {
  const start = +new Date();
  const mock = () => {
    return {
      fs: {readFile: file => new Promise((resolve, reject) => {
        // Instead of this just make three files and try each timing arrangement.
        // IE, all same, [100, 200, 300], [300, 200, 100], [100, 300, 200], etc.
        const time = Math.round(100 + Math.random() * 4900);
        console.log(`Read of ${file} started at ${new Date() - start} and will take ${time}ms.`)
        setTimeout(() => {
          // Bonus material here if random reject instead.
          console.log(`Read of ${file} finished, resolving promise at ${new Date() - start}.`);
          resolve(file);
        }, time);
      })},
      console: {log: file => console.log(`Console Log of ${file} finished at ${new Date() - start}.`)},
      getFilePaths: () => ['A', 'B', 'C', 'D', 'E']
    };
  };

  const printFiles = (({fs, console, getFilePaths}) => {
    return async function() {
      const files = (await getFilePaths()).map(file => fs.readFile(file, 'utf8'));

      for(const file of files)
        console.log(await file);
    };
  })(mock());

  console.log(`Running at ${new Date() - start}`);
  await printFiles();
  console.log(`Finished running at ${new Date() - start}`);
})();

-3

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

const async = require('async')
const fs = require('fs-promise')
const pify = require('pify')

async function getFilePaths() {
    return Promise.resolve([
        './package.json',
        './package-lock.json',
    ]);
}

async function printFiles () {
  const files = await getFilePaths()

  await pify(async.eachSeries)(files, async (file) => {  // <-- run in series
  // await pify(async.each)(files, async (file) => {  // <-- run in parallel
    const contents = await fs.readFile(file, 'utf8')
    console.log(contents)
  })
  console.log('HAMBONE')
}

printFiles().then(() => {
    console.log('HAMBUNNY')
})
// ORDER OF LOGS:
// package.json contents
// package-lock.json contents
// HAMBONE
// HAMBUNNY
```


এটি ভুল দিকের একটি পদক্ষেপ। আধুনিক জেএস যুগে কলব্যাক জাহান্নামে লোকদের আটকে রাখতে সহায়তা করার জন্য এখানে তৈরি করা একটি ম্যাপিং গাইড রয়েছে: github.com/jmjpro/async-package-to-async-await/blob/master/…
jbustamovej

আপনি এখানে দেখতে পারেন , আমি আগ্রহী এবং async lib এর পরিবর্তে async / অপেক্ষা করতে আগ্রহী। এখনই, আমি মনে করি যে প্রত্যেকের একটি সময় এবং জায়গা আছে place আমি নিশ্চিত নই যে async lib == "কলব্যাক হেল" এবং async / অপেক্ষার == "আধুনিক জেএস যুগ"। imo, async lib> async / প্রতীক্ষা করুন: 1. জটিল প্রবাহ (যেমন, জিনিসগুলি জটিল হয়ে উঠলে কাত, কার্গো, এমনকি অটোও) 2. সমঝোতা ৩. অ্যারে / অবজেক্টস / পুনরাবৃত্তিগুলি সমর্থন করে 4. ত্রুটি পরিচালনা
জ্যাকারি রায়ান স্মিথ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.