සෑම ලූපයක් සමඟම අසින්ක් / බලා සිටීම


1217

භාවිතා ඕනෑම ගැටලූ පවතින 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ඒ නිසා මම දැන් මේ සමග කිසිදු ප්රශ්නයක් තිබුණා නම් ඇසීමට අවශ්ය, මේ වගේ ඉහළ ගණයේ උත්සවයට.

Answers:


2312

කේතය ක්‍රියාත්මක වන බව විශ්වාසයි, නමුත් මට විශ්වාසයි එය ඔබ බලාපොරොත්තු වන දේ නොකරන බව. එය අසමමුහුර්ත ඇමතුම් කිහිපයක් ඉවත් කරයි, නමුත් printFilesශ්‍රිතය වහාම නැවත පැමිණේ.

අනුපිළිවෙලින් කියවීම

ඔබට ලිපිගොනු අනුපිළිවෙලින් කියවීමට අවශ්‍ය නම්, ඔබටforEach ඇත්ත වශයෙන්ම භාවිතා කළ නොහැක . ඒ for … 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)
  }));
}

39
කරුණාකර for ... of ...වැඩ කරන්නේ මන්දැයි ඔබට පැහැදිලි කළ හැකිද ?
ඩිමන්බේන්

92
හරි මම බාබෙල් පරිවර්තනය කරනු ඇත ඇයි ... භාවිතා කරමින් දන්නවා async/ awaitජනකය ක්රියාත්මක වීම හා භාවිතා forEachමාර්ගයෙන් මේ අයුරින් සෑම ප්රතිඵලයක්ම අන් අය සමග කිසි ඇති තනි ජනකය කාර්යය, ඇති බව. එබැවින් ඒවා ස්වාධීනව ක්‍රියාත්මක වන next()අතර අන් අය සමඟ සන්දර්භයක් නොමැත . ඇත්ත වශයෙන්ම, සරල for()පුඩුවක් ද ක්‍රියා කරන්නේ පුනරාවර්තන ද තනි උත්පාදක ශ්‍රිතයක පවතින බැවිනි.
ඩිමන්බේන්

21
Em ඩෙමන්බේන්: කෙටියෙන් කිවහොත්, එය වැඩ කිරීමට නිර්මාණය කර ඇති නිසා :-) සියලුම පාලන ව්‍යුහයන් ද ඇතුළුව awaitවත්මන් ශ්‍රිත ඇගයීම අත්හිටුවයි . ඔව්, එය ඒ සම්බන්ධයෙන් උත්පාදක යන්ත්රවලට බෙහෙවින් සමාන ය (ඒ නිසා ඒවා බහුඅවයවික අසමමුහුර්ත / බලා සිටීමට භාවිතා කරයි).
බර්ගි

3
ve arve0 ඇත්ත වශයෙන්ම, asyncශ්‍රිතයක් ක්‍රියාත්මක කරන්නාගේ ඇමතුමට වඩා බෙහෙවින් වෙනස් ය Promise, නමුත් ඔව්, mapඇමතුම් ලබා ගැනීම අවස්ථා දෙකේදීම පොරොන්දුවක් ලබා දෙයි.
බර්ගි

6
ඔබ JS පොරොන්දු ගැන ඉගෙන ගැනීමට පැමිණි විට, ඒ වෙනුවට පැය භාගයක් ලතින් පරිවර්තනය කරන්න. ඔබ ආඩම්බර වේ යැයි සිතමු @ බර්ගි;)
ෆීලික්ස් ගග්නොන්-ග්‍රෙනියර්

217

ES2018 සමඟ, ඔබට ඉහත පිළිතුරු සියල්ල බෙහෙවින් සරල කළ හැකිය:

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

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

පිරිවිතර බලන්න: යෝජනාව-අසංක-නැවතීමේ


2018-09-10: මෙම පිළිතුර මෑතකදී බොහෝ අවධානයට ලක්ව ඇත, කරුණාකර අසමමුහුර්ත ක්‍රියාකාරීත්වය පිළිබඳ වැඩිදුර තොරතුරු සඳහා ඇක්සෙල් රවුෂ්මේයර්ගේ බ්ලොග් සටහන බලන්න: ES2018: අසමමුහුර්ත ක්‍රියාවලිය


4
ඉහළට, අසමමුහුර්තකරණය ගැන වැඩි විස්තර දැන ගැනීමට කැමති ඕනෑම කෙනෙකුට ඔබේ පිළිතුරෙහි පිරිවිතරයට සබැඳියක් තැබිය හැකි නම් හොඳයි .
saadq


11
මිනිසුන් මෙම පිළිතුර ඉහළට ඔසවා තබන්නේ ඇයි? පිළිතුර, ප්‍රශ්නය සහ යෝජනාව දෙස සමීපව බලන්න. පසුව ofඅරාව නැවත ලබා දෙන අසින්ක් ශ්‍රිතය විය යුතුය. එය ක්‍රියාත්මක නොවන අතර ෆ්‍රැන්සිස්කෝ පැවසීය;
යෙවේනි හෙරසිම්චුක්

3
Nt ඇන්ටෝනියෝවාල් සමඟ සම්පුර්ණයෙන්ම එකඟ වන්න. එය පිළිතුරක් නොවේ.
යෙවේනි හෙරසිම්චුක්

3
එය පිළිතුරක් නොවන බව මා එකඟ වන අතර, යෝජනාවක් ඉදිරිපත් කිරීම එහි ජනප්‍රියතාවය වැඩි කර ගත හැකි ක්‍රමයක් වන අතර එය පසුව භාවිතා කිරීමට පෙර ලබා ගත හැකිය.
රොබට් මොලිනා

67

( S නිරාකරණය කර ඇති අනුපිළිවෙල සහතික නොකරන) Promise.allසමඟ සමපාත වීම වෙනුවට , මම භාවිතා කරන්නේ , නිරාකරණයෙන් පටන් ගෙන :Array.prototype.mapPromiseArray.prototype.reducePromise

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
r parrker9 Promise.resolve()විසින් දැනටමත් විසඳා ඇති Promiseවස්තුවක් නැවත ලබා දෙයි , එවිට reduceඑය Promiseආරම්භ කළ යුතුය. දාමයේ await promise;අන්තිමයා Promiseවිසඳීමට බලා සිටිනු ඇත . OlGollyJer ලිපිගොනු එකවර එකවර සැකසෙනු ඇත.
තිමෝති සෝන්

අඩු කිරීම ඉතා සිසිල් භාවිතය, අදහස් දැක්වීමට ස්තූතියි! අදහස් දැක්වීමේදී සඳහන් කර ඇති වෙනත් ක්‍රම කිහිපයකට වඩා වෙනස්ව, මෙය සමමුහුර්ත බව මම දක්වන්නෙමි, එයින් අදහස් වන්නේ ලිපිගොනු එකින් එක කියවන අතර සමාන්තරව නොවේ (අඩු කිරීමේ ශ්‍රිතයේ ඊළඟ ක්‍රියාකාරීත්වය පෙර මත රඳා පවතින බැවින් පුනරාවර්තනය, එය සමමුහුර්ත විය යුතුය).
ෂේ යෂකොව්

1
Ha ෂේ, ඔබ අදහස් කළේ අනුක්‍රමික මිස සමමුහුර්ත නොවේ. මෙය තවමත් අසමමුහුර්තයි - වෙනත් දේවල් උපලේඛනගත කර ඇත්නම්, ඒවා මෙහි පුනරාවර්තන අතර ක්‍රියාත්මක වේ.
තිමෝති සෝන්

33

එන්පීඑම් හි p-iteration මොඩියුලය අරා පුනරාවර්තන ක්‍රම ක්‍රියාත්මක කරන අතර එමඟින් ඒවා ඉතා සරල ආකාරයකින් අසින්ක් / අපේක්ෂාවෙන් භාවිතා කළ හැකිය.

ඔබේ නඩුව සමඟ උදාහරණයක්:

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
මම මේකට කැමතියි එයට JS හා සමාන කාර්යයන් / ක්‍රම තිබෙන නිසා - මගේ නඩුවේදී මට අවශ්‍ය වූයේ someඊට වඩා forEach. ස්තූතියි!
mikemaccana

29

මෙන්න 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));
}

සටහන ඔබ ඔබේ ම කේතය මෙම ඇතුළත් විය හැකිය අතර, ඔබ (ඔවුන්ගේ globals දූෂණය වළක්වා ගැනීමට) ඔබ අන් අයට බෙදා පුස්තකාල මෙම ඇතුළත් කළ යුතු නැහැ.


1
මූලාකෘතියට කෙලින්ම දේවල් එකතු කිරීමට මා අදිමදි කළද, මෙය සෑම ක්‍රියාවට නැංවීම සඳහාම හොඳ අසංකයකි
ඩැනියෝ ඕෂන්

2
අනාගතයේදී නම අද්විතීය වන තාක් කල් (මම භාවිතා කිරීමට කැමති පරිදි _forEachAsync) මෙය සාධාරණ ය. බොයිලර් ප්ලේට් කේත විශාල ප්‍රමාණයක් ඉතිරි කරන බැවින් එය හොඳම පිළිතුර යැයි මම සිතමි.
mikemaccana

1
@estus එනම් අනෙක් පුද්ගලයින්ගේ කේතය දූෂණය වීම වළක්වා ගැනීමයි. කේතය අපගේ පුද්ගලික සංවිධානයට අයත් නම් සහ ග්ලෝබල් හොඳින් හඳුනාගත් ගොනුවක තිබේ නම් ( globals.jsහොඳයි) අපට කැමති පරිදි ග්ලෝබල් එකතු කළ හැකිය.
mikemaccana

1
ikemikemaccana එය සාමාන්‍යයෙන් පිළිගත් නරක පුරුදු වලක්වා ගැනීමයි. එය සත්‍යයකි, ඔබ පළමු-පාර්ශවීය කේතය පමණක් භාවිතා කරන තාක් කල් මෙය කළ හැකි අතර එය කලාතුරකින් සිදු වේ. ගැටලුව වන්නේ ඔබ තෙවන පාර්ශවීය ලිබ් භාවිතා කරන විට, එකම ආකාරයකින් දැනෙන සහ එකම ගෝලීය වෙනස් කරන වෙනත් පුද්ගලයෙක් සිටිය හැකිය, එය ලිබ් ලියන අවස්ථාවේ හොඳ අදහසක් ලෙස පෙනුණු නිසා ය.
එස්ටස් ෆ්ලස්ක්

1
ෂෙස්ටස් ෂුවර්. (විශේෂයෙන් tive ලදායී නොවන) සාකච්ඡාව මෙහි සුරැකීමට මම ප්‍රශ්නයට අනතුරු ඇඟවීමක් එක් කළෙමි.
mikemaccana

7

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') අනිවාර්යයෙන්ම 3 වන තර්ක ලෙස ක්‍රියා කරයි, එසේ නොමැතිනම් දෝෂය විසි කරයි:

TypeError [ERR_INVALID_CALLBACK]: Callback must be a function

7

අමතරව @ Bergi පිළිතුර , මම තුන්වන විකල්පයක් ඉදිරිපත් කිරීමට කැමතියි. එය @ බර්ගීගේ 2 වන උදාහරණයට බොහෝ සෙයින් සමාන ය, නමුත් එක් එක් 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()අවශ්‍ය නොවන බව සලකන්න . එබැවින් පොරොන්දු වස්තු සමූහයක් වන අතර එය යැවිය හැකිය .asyncfs.readFilepromisesPromise.all()

@ බර්ගීගේ පිළිතුරෙන්, කොන්සෝලය කියවන අනුපිළිවෙලට ගොනු අන්තර්ගතයන් ලොග් කළ හැකිය. උදාහරණයක් ලෙස කුඩා ගොනුවක් විශාල ගොනුවකට පෙර කියවීම අවසන් කළහොත් , අරාවෙහි ඇති විශාල ගොනුවට පසුව කුඩා ගොනුව පැමිණියද එය පළමුව ලොග් වනු ඇත files. කෙසේ වෙතත්, ඉහත මගේ ක්‍රමයේදී, කොන්සෝලය විසින් සපයන ලද අරාවෙහි ආකාරයටම ලිපිගොනු ලොග් කරනු ඇති බවට ඔබට සහතිකයි.


1
ඔබ වැරදියි කියා මට හොඳටම විශ්වාසයි: ඔබේ ක්‍රමයටද ලිපිගොනු පිළිවෙලට කියවිය හැකි බව මට විශ්වාසයි. ඔව්, එය ප්‍රතිදානය නිවැරදි අනුපිළිවෙලට ලොග් කරනු ඇත (නමුත් නිසා await Promise.all) ගොනු වෙනත් අනුපිළිවෙලකින් කියවා ඇති අතර එය ඔබේ ප්‍රකාශයට පටහැනි වේ "කොන්සෝලය ලිපිගොනු එකම අනුපිළිවෙලට ලොග් කරන බවට ඔබට සහතිකයි කියවන්න".
Venryx

1
En වෙන්රික්ස් ඔබ හරි, නිවැරදි කිරීමට ස්තූතියි. මම මගේ පිළිතුර යාවත්කාලීන කර ඇත.
චාර්වි

5

කෙසේ වෙතත්, ඉහත විසඳුම් දෙකම, අඩු කේතයකින් ඇන්ටෝනියෝගේ කාර්යය ඉටු කරයි, මෙන්න එය මගේ දත්ත ගබඩාවෙන්, විවිධ ළමා යොමු කිහිපයකින් දත්ත නිරාකරණය කර ගැනීමට උපකාරී වූ ආකාරය සහ පසුව ඒවා සියල්ලම පෙළට තල්ලු කර පොරොන්දුවක් ලෙස විසඳා ගැනීම අවසන්:

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)))

4

අනුක්‍රමික අනුපිළිවෙලකට අසමමුහුර්ත දත්ත හැසිරවිය හැකි සහ ඔබේ කේතයට වඩාත් සාම්ප්‍රදායික රසය ලබා දෙන ගොනුවක ක්‍රම කිහිපයක් පොප් කිරීම ඉතා වේදනාකාරී ය. උදාහරණයක් වශයෙන්:

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
සුළු එකතු කිරීම, ඔබගේ අපේක්ෂාව / අසින්ක්ස් උත්සාහක / අල්ලා ගැනීමේ කොටස් වලින් ඔතා ගැනීමට අමතක නොකරන්න !!
ජේ එඩ්වර්ඩ්ස්

4

@ බර්ගීගේ ප්‍රතිචාරය මෙන්, නමුත් එක් වෙනසක් සමඟ.

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()

පීඑස්

readFilesQueueපිටත ඇත printFilesපැත්ත ක්රියාත්මක * විසින් හඳුන්වා හේතුව console.log, එය, පරීක්ෂණ නිග්රහ කිරීමට වඩා හොඳ වන අතර, හෝ එසේ ඔත්තු, එය අන්තර්ගතය (sidenote) නැවත එම උත්සවයකට ඇති සිසිල් නොවේ.

එමනිසා, කේතය සරලව නිර්මාණය කළ හැක්කේ: “පිරිසිදු” ** ලෙස වෙන් කරන ලද ශ්‍රිත තුනක් සහ කිසිදු අතුරු ආබාධයක් හඳුන්වා නොදීම, සම්පූර්ණ ලැයිස්තුවම සැකසීම සහ අසමත් වූ අවස්ථා හැසිරවීම සඳහා පහසුවෙන් වෙනස් කළ හැකිය.

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)

අනාගත සංස්කරණය / වත්මන් තත්වය

Node ඉහළ මට්ටමේ බලා සිටීම සඳහා සහය දක්වයි (මෙයට තවමත් ප්ලගිනයක් නොමැත, සමගිය කොඩි හරහා සක්‍රීය කළ නොහැක), එය සිසිල් නමුත් එක් ගැටළුවක් විසඳන්නේ නැත (උපායමාර්ගිකව මම වැඩ කරන්නේ LTS අනුවාදවල පමණි). ලිපිගොනු ලබා ගන්නේ කෙසේද?

සංයුතිය භාවිතා කිරීම. කේතය අනුව, මෙය මොඩියුලයක් තුළ ඇති බවට මට හැඟීමක් ඇති කරයි, එබැවින් එය කිරීමට ශ්‍රිතයක් තිබිය යුතුය. එසේ නොවේ නම්, ඔබ විසින් IIFE භාවිතා කර භූමිකාව කේතය අසමමුහුර්ත ශ්‍රිතයක් තුළට ඔතා සරල මොඩියුලයක් නිර්මාණය කර ඔබ වෙනුවෙන් සියල්ලම කළ හැකිය, නැතහොත් ඔබට නිවැරදි මාර්ගයෙන් යා හැකිය, සංයුතිය ඇත.

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

අර්ථ නිරූපණය හේතුවෙන් විචල්‍ය වෙනස්වීම්වල නම සටහන් කරන බව සලකන්න. ඔබ ෆන්ක්ටර් එකක් (වෙනත් ශ්‍රිතයක් මඟින් ආයාචනය කළ හැකි ශ්‍රිතයක්) පසු කර යෙදුමේ තර්කනයේ ආරම්භක කොටස අඩංගු මතකය පිළිබඳ දර්ශකයක් ලබා ගනී.

නමුත්, මොඩියුලයක් නොවේ නම් සහ ඔබට තර්කනය අපනයනය කළ යුතුද?

අසංක ශ්‍රිතයක කාර්යයන් ඔතා.

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

නැතහොත් විචල්‍යයන්ගේ නම් වෙනස් කරන්න, කුමක් වුවත් ...


* IO වැනි යෙදුමේ ප්‍ර stat ප්තිය / හැසිරීම වෙනස් කිරීමට හෝ යෙදුමේ දෝෂ හඳුන්වා දිය හැකි යෙදුමේ ඕනෑම සමෝධානික බලපෑමක් අතුරු by ල වේ.

** "නිර්මල" මගින්, එය ප්‍රේරිතයේ පවතින බැවින් එය පිරිසිදු නොවන අතර කේතය පිරිසිදු අනුවාදයකට පරිවර්තනය කළ හැකිය, කොන්සෝල ප්‍රතිදානය නොමැති විට දත්ත හැසිරවීම් පමණි.

මේ හැරුණු විට, පිරිසිදු වීමට නම්, අතුරු ආබාධ හසුරුවන, දෝෂ ඇතිවිය හැකි මොනාඩ් සමඟ වැඩ කිරීමට ඔබට අවශ්‍ය වන අතර, එම දෝෂය යෙදුමට වෙන වෙනම සලකයි.


3

එක් වැදගත් අවවාදයක් නම්: 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()
)

නැතහොත් ඔබට උදව් කිරීම සඳහා forEachAsync නිර්මාණය කළ හැකි නමුත් මූලික වශයෙන් එය ලූප යටින් භාවිතා කරන්න.

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

Array.prototype සහ Object.prototype හි javascript හි ක්‍රමය නිර්වචනය කරන්නේ කෙසේදැයි බලන්න, එවිට එය ලූපය තුළ නොපෙන්වයි . තවද ඔබ බොහෝ විට ස්වදේශික ලෙසම නැවත භාවිතා කිරීම භාවිතා කළ යුතුය forEach- ක්‍රියාකාරීත්වය මත රඳා සිටීම වෙනුවට දර්ශක වෙත ප්‍රවේශ වීම - සහ දර්ශකය ඇමතුම් ආපසු ලබා දෙන්න.
බර්ගි

ඔබට Array.prototype.reduceඅසින්ක් ශ්‍රිතයක් භාවිතා කරන ආකාරයකින් භාවිතා කළ හැකිය. මම මගේ පිළිතුරෙහි උදාහරණයක් පෙන්වා ඇත: stackoverflow.com/a/49499491/2537258
තිමෝති සෝර්න්

3

කාර්යය, අනාගතය සහ ගමන් කළ හැකි ලැයිස්තුවක් භාවිතා කිරීමෙන් ඔබට සරලව කළ හැකිය

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')

PS - මම මෙම කේතය කොන්සෝලය මත අත්හදා බැලුවේ නැත, යතුරු ලියනයක තිබිය හැකිය ... "කෙළින්ම නිදහස් විලාසිතාව, ගෝලාකාර මුදුනේ සිට!" 90 දශකයේ ළමයින් පවසන පරිදි. :-p


3

දැනට Array.forEach මූලාකෘති දේපල අසයික් මෙහෙයුම් සඳහා සහය නොදක්වයි, නමුත් අපගේ අවශ්‍යතා සපුරාලීම සඳහා අපට අපගේම බහු-පිරවීමක් නිර්මාණය කළ හැකිය.

// 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

... සහ යනාදි :)

සැලකිල්ලට ගත යුතු කරුණු කිහිපයක්:

  • ඔබේ iteratorFunction අසමමුහුර්ත ශ්‍රිතයක් හෝ පොරොන්දුවක් විය යුතුය
  • පෙර සාදන ලද ඕනෑම අරා Array.prototype.<yourAsyncFunc> = <yourAsyncFunc>වල මෙම අංගය ලබා ගත නොහැක

3

මුල් පිළිතුරට එකතු කිරීම පමණි

  • මුල් පිළිතුරේ සමාන්තර කියවීමේ වාක්‍ය ඛණ්ඩය සමහර විට ව්‍යාකූල සහ කියවීමට අපහසු වේ, සමහර විට අපට එය වෙනත් ප්‍රවේශයකින් ලිවිය හැකිය
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);
  }
}

3

මෙම විසඳුම මතකය ප්‍රශස්ත කර ඇති බැවින් ඔබට 10,000 ක දත්ත අයිතම සහ ඉල්ලීම් මත එය ක්‍රියාත්මක කළ හැකිය. මෙහි ඇති වෙනත් විසඳුම් විශාල දත්ත කට්ටල මත සේවාදායකය බිඳ වැටෙනු ඇත.

TypeScript හි:

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 ...
})

2

එය වැරදිය හැක්කේ කෙසේදැයි බැලීමට, ක්‍රමවේදය අවසානයේ console.log මුද්‍රණය කරන්න.

පොදුවේ වැරදියට සිදුවිය හැකි දේවල්:

  • අත්තනෝමතික අනුපිළිවෙල.
  • printFiles ගොනු මුද්‍රණය කිරීමට පෙර ධාවනය අවසන් කළ හැකිය.
  • දුර්වල කාර්ය සාධනය.

මේවා සැමවිටම වැරදි නොවන නමුත් නිතර භාවිතා වන්නේ සම්මත භාවිත අවස්ථා වලය.

සාමාන්‍යයෙන්, forEach භාවිතා කිරීමෙන් අන්තිම දේ හැර අන් සියල්ලටම ප්‍රති result ල ලැබෙනු ඇත. එය ශ්‍රිතය එනතෙක් බලා නොසිට සෑම ශ්‍රිතයක්ම අමතනු ඇත. එහි අර්ථය එය සියලු කාර්යයන් ආරම්භ කිරීමට පවසන අතර පසුව කාර්යයන් අවසන් වන තෙක් බලා නොසිට අවසන් වේ.

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()

මෙය ස්වදේශීය ජේඑස් හි උදාහරණයකි, එය පිළිවෙල ආරක්ෂා කරයි, ක්‍රියාකාරීත්වය අකාලයේ නැවත පැමිණීම වලක්වනු ඇත.

මෙය:

  • සියලුම ලිපිගොනු කියවීම් සමාන්තරව සිදුවීමට පටන් ගන්න.
  • පොරොන්දු වන තෙක් ගොනු නාම සිතියම් ගත කිරීම සඳහා සිතියම භාවිතා කරමින් ඇණවුම ආරක්ෂා කරන්න.
  • අරාව මගින් අර්ථ දක්වා ඇති අනුපිළිවෙලෙහි එක් එක් පොරොන්දුව සඳහා රැඳී සිටින්න.

මෙම විසඳුම සමඟ පළමු ගොනුව ලබා ගත හැකි ඉක්මනින් අනෙක් ඒවා ලබා ගත හැකි තෙක් බලා නොසිට පෙන්වනු ඇත.

දෙවන ලිපිගොනු කියවීම ආරම්භ කිරීමට පෙර පළමු ලිපිගොනු අවසන් වන තෙක් බලා සිටීමට වඩා එය එකවර සියලුම ලිපිගොනු පටවනු ඇත.

මෙහි ඇති එකම පසුබෑම වන්නේ මුල් පිටපත නම් එකවර කියවීම් කිහිපයක් ආරම්භ කළහොත් වරකට සිදුවිය හැකි තවත් දෝෂ ඇති බැවින් දෝෂ හැසිරවීම වඩාත් අපහසු වේ.

වරකට ගොනුවක් කියවන අනුවාදයන් සමඟ තවත් ලිපිගොනු කියවීමට කාලය නාස්ති නොකර අසාර්ථක වනු ඇත. විස්තීර්ණ අවලංගු කිරීමේ පද්ධතියක් සමඟ වුවද එය පළමු ගොනුවේ අසමත් වීම වළක්වා ගැනීම දුෂ්කර විය හැකි නමුත් අනෙක් ලිපිගොනු බොහොමයක් දැනටමත් කියවා ඇත.

කාර්ය සාධනය සැමවිටම අනාවැකි කිව නොහැක. සමාන්තර ලිපිගොනු කියවීම් සමඟ බොහෝ පද්ධති වේගවත් වන අතර සමහර ඒවා අනුක්‍රමිකව කැමති වේ. සමහර ඒවා ගතික වන අතර බර පැටවිය හැකිය, ප්‍රමාද වීම ලබා දෙන ප්‍රශස්තිකරණය සෑම විටම දැඩි මතභේද යටතේ හොඳ ප්‍රති put ල ලබා නොදේ.

එම උදාහරණයේ දෝෂ හැසිරවීමක් ද නොමැත. යමක් සාර්ථකව පෙන්වීමට හෝ අවශ්‍ය නොවීමට යමක් අවශ්‍ය නම් එය එසේ නොකරනු ඇත.

සෑම අදියරකදීම console.log සහ ව්‍යාජ ලිපිගොනු කියවීමේ විසඳුම් (ඒ වෙනුවට අහඹු ප්‍රමාදය) සමඟ ගැඹුරින් අත්හදා බැලීම නිර්දේශ කෙරේ. බොහෝ විසඳුම් සරල අවස්ථා වලදී එකම දේ කරන බවක් පෙනෙන්නට තිබුණද, සියල්ලටම සියුම් වෙනස්කම් ඇති අතර ඒවා මිරිකීම සඳහා අමතර පරීක්ෂාවක් අවශ්‍ය වේ.

විසඳුම් අතර වෙනස පැවසීමට මෙම විහිළුව භාවිතා කරන්න:

(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}`);
})();

2

අද මට මේ සඳහා විවිධ විසඳුම් හමු විය. සෑම ලූප් එකකම අසින්ක් ධාවනය කිරීම බලා‍පොරොත්තු වේ. එතීම වටා එතීමෙන් අපට මෙය සිදුවිය හැකිය.

එය අභ්‍යන්තරව ක්‍රියා කරන්නේ කෙසේද යන්න පිළිබඳ වඩාත් සවිස්තරාත්මක පැහැදිලි කිරීමක්, සෑම අයෙකුටම ස්වදේශිකයා සඳහා සහ එයට අසයික් ශ්‍රිත ඇමතුමක් ලබා ගැනීමට නොහැකි වූයේ ඇයි සහ විවිධ ක්‍රම පිළිබඳ වෙනත් තොරතුරු මෙහි සබැඳියෙන් දක්වා ඇත

එය කළ හැකි විවිධ ක්‍රම සහ ඒවා පහත පරිදි වේ,

ක්රමය 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 හි සාමාන්‍ය ශ්‍රිතයක් ලෙස භාවිතා කිරීම

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:

Promise.all භාවිතා කිරීම

  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භාවිතා කළ යුතුව තිබූ වැරදි ක්‍රියාවට නැංවීමකි - ඒවා බොහෝ අද්දර සිද්ධීන් කිසිවක් සැලකිල්ලට නොගනී.
බර්ගි

Er බර්ගි: වලංගු අදහස් දැක්වීම් වලට ස්තූතියි, කරුණාකර 1 සහ 2 ක්‍රමය වැරදියි කියා මට පැහැදිලි කරන්න. එය ද අරමුණ ඉටු කරයි. මෙය ඉතා හොඳින් ක්‍රියාත්මක වේ. මෙයින් කියැවෙන්නේ මෙම ක්‍රම සියල්ලම හැකි ය, එය තෝරා ගැනීමේදී තීරණය කළ හැකි තත්ත්වය මත ය. මට ඒ සඳහා ධාවන ආදර්ශය ඇත.
PranavKAndro

එය හිස් අරා මත අසමත් වේ, එයට දෝෂ හැසිරවීමක් නොමැත, බොහෝ විට තවත් ගැටලු ඇත. රෝදය ප්‍රතිනිර්මාණය නොකරන්න. භාවිතා කරන්න Promise.all.
බර්ගි

එය කළ නොහැකි ඇතැම් තත්වයන් තුළ එය ප්‍රයෝජනවත් වනු ඇත. පෙරනිමියෙන් සෑම api විසින්ම දෝෂ හැසිරවීම සිදු කරයි, එබැවින් ගැටළු නොමැත. එය බලා ගනී!
ප්‍රණව් කේ ඇන්ඩ්‍රෝ

නැත, Promise.allකළ නොහැකි නමුත් async/ awaitපවතින කොන්දේසි නොමැත . නැත, forEachපරම ඕනෑම පොරොන්දුවක් දෝෂ හැසිරවීම නොවේ.
බර්ගි

2

ඔබට භාවිතා කළ හැකිය Array.prototype.forEach, නමුත් අසංක / බලා සිටීම එතරම් අනුකූල නොවේ. මෙයට හේතුව, අසින්ක් ඇමතුමකින් ආපසු ලබා දෙන පොරොන්දුව විසඳීමට අපේක්ෂා කරන නමුත් 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)
}

1
පළමු සෙනරියෝ සීරිය තුළ ධාවනය කළ යුතු ලූප සඳහා වඩාත් සුදුසු වන අතර ඔබට ඒවා භාවිතා කළ නොහැක
මාර්ක් ඔඩේ

0

ඇන්ටෝනියෝ වැල්ට සමාන p-iteration, විකල්ප npm මොඩියුලයක් 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පොරොන්දු වල ප්‍රති log ල සටහන් කරන ස්ථිතික ක්‍රමයක් (ලොග් / ලොග්ඒඑෆ්) ඇත:

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


-3

මම හොඳින් පරීක්ෂා (සතියකට බාගත කිරීම් මිලියන ගණනක්) භාවිතා කරන pify හා අසමකාලීක මොඩියුල. ඔබ අසින්ක් මොඩියුලය ගැන නුහුරු නම්, එහි ලේඛන පරීක්ෂා කර බැලීමට මම තරයේ නිර්දේශ කරමි . ඉහළ පෙළේ අසින්ක් ක්‍රම මඟින් කේතය සරල කරන විට බහු ඩිව්ස් නාස්ති කිරීමේ කාලය එහි ක්‍රම ප්‍රතිනිර්මාණය කිරීම හෝ ඊට වඩා නරක ලෙස මම දැක ඇත්තෙමි.

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 == "callback hell" සහ async / wait == "නූතන JS යුගය" බව මට ඒත්තු ගොස් නැත. imo, විට අසින්ක් ලිබ්> අසින්ක් / බලා සිටින්න: 1. සංකීර්ණ ප්‍රවාහය (උදා: පෝලිම්, භාණ්ඩ, දේවල් පවා සංකීර්ණ වූ විට ස්වයංක්‍රීයව) 2. සමගාමී මුදල් 3. ආධාරක අරා / වස්තු / පුනරාවර්තන 4. වැරදි හැසිරවීම
සැකරි රයන් ස්මිත්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.