English 中文(简体)
• 每一 lo
原标题:Using async/await with a forEach loop

是否有任何问题在<条码>上使用<条码>条码>。 I m试图通过一系列档案和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()

这部法律确实可行,但可能有一些错误? 我有人告诉我,你不应在像现在这样更高级的职能中使用<条码>。

最佳回答

确保守则行之有效,但我很相信,它没有做你预计要做的事情。 它只是向多个星号开火,但Files 功能随即返回。

Reading in sequence

如果您希望按顺序阅读这些档案, 确实不能使用forEach。 仅使用一个现代的<代码>(>for...... of loop>,其中await将按预期运作:

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

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

Reading in parallel

If you want to read the files in parallel, you cannot use forEach indeed. Each of the async callback function calls does return a promise, but you re throwing them away instead of awaiting them. Just use map instead, and you can await the array of promises that you ll get with 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)
  }));
}
问题回答

有了ES-2018,你能够大大简化上述所有答复:

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

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

See spec: proposal-async-iteration

Simplified:

  for await (const results of array) {
    await longRunningTask()
  }
  console.log( I will wait )

2018-09-10: 这一答复最近引起了很多关注,请见Axel Rauschmayer s blog post,以进一步了解关于仓储的频率。

而不是Promise.allArray.prototype.map。 (这并不保证<代码>的次序) Promises are addressed, I use Array.prototype.reduce/code>,start with a resolution 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());
}
files.forEach(async (file) => {
    const contents = await fs.readFile(file,  utf8 )
})

The issue is, the promise returned by the iteration function is ignored by forEach(). forEach does not wait to move to the next iteration after each async code execution is completed. All the fs.readFile functions will be invoked in the same round of the event loop, which means they are started in parallel, not in sequential, and the execution continues immediately after invoking forEach(), without waiting for all the fs.readFile operations to complete. Since forEach does not wait for each promise to resolve, the loop actually finishes iterating before promises are resolved. You are expecting that after forEach is completed, all the async code is already executed but that is not the case. You may end up trying to access values that are not available yet.

你们可以按照这一榜样法检验行为。

const array = [1, 2, 3];

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const delayedSquare = (num) => sleep(100).then(() => num * num);

const testForEach = (numbersArray) => {
  const store = [];
  // this code here treated as sync code
  numbersArray.forEach(async (num) => {
    const squaredNum = await delayedSquare(num);
    // this will console corrent squaredNum value
    // console.log(squaredNum) will log after console.log("store",store)
    console.log(squaredNum);
    store.push(squaredNum);
  });
  // you expect that store array is populated as [1,4,9] but it is not
  // this will return []
  console.log("store",store);
};
testForEach(array);
// Notice, when you test, first "store []" will be logged
// then squaredNum s inside forEach will log

解决办法是利用 lo。

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

Picture worth 1000 words - For Sequential Approach Only


www.un.org/Depts/DGACM/index_russian.htm 昨天晚上,我的情况类似。 我将“合成”作为每一论点。 结果是无法预测的。 当我对我的法典进行了3次测试时,它没有问题2次,没有时间。 (约合编)

最后,我直面和安放,做一些rat子检测。

Scenario 1 - How un-sequential it can get with async in foreach

“entergraph

const getPromise = (time) => { 
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`Promise resolved for ${time}s`)
    }, time)
  })
}

const main = async () => {
  const myPromiseArray = [getPromise(1000), getPromise(500), getPromise(3000)]
  console.log( Before For Each Loop )

  myPromiseArray.forEach(async (element, index) => {
    let result = await element;
    console.log(result);
  })

  console.log( After For Each Loop )
}

main();

Scenario 2 - Using for - of loop as @Bergi above suggested

“entergraph

const getPromise = (time) => { 
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`Promise resolved for ${time}s`)
    }, time)
  })
}

const main = async () => {
  const myPromiseArray = [getPromise(1000), getPromise(500), getPromise(3000)]
  console.log( Before For Each Loop )

  // AVOID USING THIS
  // myPromiseArray.forEach(async (element, index) => {
  //   let result = await element;
  //   console.log(result);
  // })

  // This works well
  for (const element of myPromiseArray) {
    let result = await element;
    console.log(result)
  }

  console.log( After For Each Loop )
}

main();

如果像我一样,你很少是老学校,那么你就可以简单地利用古典修女,这样工作也一样:

const getPromise = (time) => { 
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`Promise resolved for ${time}s`)
    }, time)
  })
}

const main = async () => {
  const myPromiseArray = [getPromise(1000), getPromise(500), getPromise(3000)]
  console.log( Before For Each Loop )

  // AVOID USING THIS
  // myPromiseArray.forEach(async (element, index) => {
  //   let result = await element;
  //   console.log(result);
  // })

  // This works well too - the classic for loop :)
  for (let i = 0; i < myPromiseArray.length; i++) {
    const result = await myPromiseArray[i];
    console.log(result);
  }

  console.log( After For Each Loop )
}

main();

我希望这能帮助人、好日、che!

https://github.com/toniov/p-iteration”rel=“noreferer”>p-iteration 乳房模块采用阿雷射电解方法,以便能够以非常直截的方式与yn/awa合使用。

例举:

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

此处为/code>原型。 请注意<代码>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));
}

,虽然你可以把这一点列入自己的法典,但你不应将这一点列入你向他人分发的图书馆(以避免污染其全球)。

To use:

await myArray. forEachAsyncParallel( async (item) => { await myAsyncFunction(item) })

Note you ll need a modern too like esrun to use await at the top level in TypeScript.

@Bergi has already gave the answer on how to handle this particular case properly. I ll not duplicate here.

我愿谈谈for Each和for之间的区别。 编号:asyncawait

请看forEach。 根据ECMA 具体规定,MDN提供了,<>>。 可用作多填充。 我在此抄录并附上摘述意见。

Array.prototype.forEach = function (callback, thisArg) {
  if (this == null) { throw new TypeError( Array.prototype.forEach called on null or undefined ); }
  var T, k;
  var O = Object(this);
  var len = O.length >>> 0;
  if (typeof callback !== "function") { throw new TypeError(callback +   is not a function ); }
  if (arguments.length > 1) { T = thisArg; }
  k = 0;
  while (k < len) {
    var kValue;
    if (k in O) {
      kValue = O[k];
      callback.call(T, kValue, k, O); // pay attention to this line
    }
    k++;
  }
};

让我回头看一下你的法典,把呼吁作为一种功能。

async function callback(file){
  const contents = await fs.readFile(file,  utf8 )
  console.log(contents)
}

因此,基本上在<条码>背书上报了承诺书,因为它以<条码>宣布。 。 相反,它把<代码>promise放在工作岗位上,并继续实施该休息室。

www.un.org/Depts/DGACM/index_spanish.htm 如何在<条码>查询内查询?

基本上,当您的作为时,请参见。 碎片发动机获得执行的机会,将暂停使用至<代码>fs.readFile(file, utf8 )待解决或拒绝,并在完成后恢复执行作为同功能。 因此,<代码>contents 各式各式各样,储存了<编码>fs.readFile的实际结果,而不是promise。 因此,console.log(contents)登录在文档内容上而不是。 Promise

www.un.org/Depts/DGACM/index_spanish.htm 为什么for work?

当我们为的左翼写一个通用的<代码>时,我们获得的控制权大于<代码>。 ∗∗∗∗∗∗∗

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

  for (const file of files) {
    const contents = await fs.readFile(file,  utf8 )
    console.log(contents)
    // or await callback(file)
  }
}

在评价<条码>时,我们有<条码>。 <代码>sync功能内的许诺,在<代码>await许诺得到解决之前,执行将暂停。 因此,你可以认为,这些档案按既定顺序逐个阅读。

www.un.org/Depts/DGACM/index_spanish.htm 平均顺序

有时,我们确实需要按顺序履行作为整体的职能。 例如,我有几处新记录储存在一个阵列中,可以保存到数据库中,我希望按顺序保存这些记录,这意味着首先应当保存一个阵列的记录,其次,直到最后一个记录得到保存为止。

例如:

const records = [1, 2, 3, 4];

async function saveRecord(record) {
  return new Promise((resolved, rejected) => {
    setTimeout(()=> {
      resolved(`record ${record} saved`)
    }, Math.random() * 500)
  });
}

async function forEachSaveRecords(records) {
  records.forEach(async (record) => {
    const res = await saveRecord(record);
    console.log(res);
  })
}

async function forofSaveRecords(records) {
  for (const record of records) {
    const res = await saveRecord(record);
    console.log(res);
  }
}
(async () => {
  console.log("=== for of save records ===")
  await forofSaveRecords(records)
  
  console.log("=== forEach save records ===")
  await forEachSaveRecords(records)
})()

I use setout to simulate the process of Save a Records to database - it s asynchronous and cost a arbitrary time. 利用forEach,记录按未确定的顺序保存,但使用for.of,这些记录按顺序保存。

这一解决办法也是以记忆为动力的,这样你就可以在10 000个数据项目和要求上运行。 这里的其他一些解决办法将毁掉大型数据集的服务器。

www.un.org/Depts/DGACM/index_spanish.htm 类型:

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

www.un.org/Depts/DGACM/index_spanish.htm 如何使用?

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

取代<条码>的简单下限办法(<>对>/代码>)有待于运行的路程替换为<条码>对每一条<条码>,代之以<条码>,并添加<条码>Promise.all()。

例如:

<>code>await y.forEach (async (x) =>{

纽约总部

<>code>await Promise.all(y.map(async (x) =>{

结尾处需要附加<代码>。

在一个将按序列顺序处理超常数据并更符合常规的手法的档案中,用双手方法收集双手法是无尽的。 例如:

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;
  };
};

现在,假定在M.Async.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));
}

Bergi s solution works nicely when fs is promise based. You can use bluebird, fs-extra or fs-promise for this.

However, solution for node s native fs libary is as follows:

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

Note: require( fs ) compulsorily takes function as 3rd arguments, otherwise throws error:

TypeError [ERR_INVALID_CALLBACK]: Callback must be a function

不要把一刀切的方法从 lo中.。 这是因为,每艘护航将推迟到整个同步作业完成之后。 这并不是非常干.的。 它还避免了<代码>sync/>/await的平行化好处。

更好的解决办法是一劳永逸地创造所有承诺,然后利用<条码>Promise.all(<>获取结果。 否则,每次连续作业都不会开始,直到以前完成。

Consequently, the code may be refactored as follows;

const printFiles = async () => {
  const files = await getFilePaths();
  const results = [];
  files.forEach((file) => {
    results.push(fs.readFile(file,  utf8 ));
  });
  const contents = await Promise.all(results);
  console.log(contents);
}

一个重要的caveat是:await + for . of methods and the for Each + async way 实际效果不同。

插入awaitin a real for 休息将确保所有星号都由一个人执行。 和forEach + async 与此同时,所有承诺也会被击退,这种承诺是更快的,有时是过度的()。 如果你做一些非行问询或访问某些网络服务,限制数量:,并不想在某个时候发射10万次电话。

如果你不使用<条码>条码/日码<>,则你也可使用<<>条码>。

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.forEach,但作为ync/await不能兼容。 这是因为,从联合呼吁中恢复的许诺预计会得到解决,但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
}

Here is a way (still using Array.prototype.forEach) to print the contents of files in parallel

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

仅增加原始答复

  • The parallel reading syntax in the original answer is sometimes confusing and difficult to read, maybe we can write it in a different approach
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);
}

  • For sequential operation, not just for...of, normal for loop will also work
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段

是否在每一 lo中使用yn/awa? ......

was covered to an extent in @Bergi s selected answer, which showed how to process in serial and in parallel. However there are other issues noted with parallelism -

  1. Order -- @chharvey notes that -

例如,如果一个小的档案在真正庞大的档案之前完成阅读,那么,即使小档案是在文件阵列中大案卷之后提交的,它就将首先记录下来。

  1. Possibly opening too many files at once -- A comment by Bergi under another answer

It is also not good to open thousands of files at once to read them concurrently. One always has to do an assessment whether a sequential, parallel, or mixed approach is better.

So let s address these issues showing actual code that is brief and concise, and does not use third party libraries. Something easy to cut, paste, and modify.

Reading in parallel (all at once), printing in serial (as early as possible per file).

最容易改进的是,如@Bergi swer,但作小改动,以便每个档案都尽快印制<>,同时保留<>/em>。

async function printFiles2() {
  const readProms = (await getFilePaths()).map((file) =>
    fs.readFile(file, "utf8")
  );
  await Promise.all([
    await Promise.all(readProms),                      // branch 1
    (async () => {                                     // branch 2
      for (const p of readProms) console.log(await p);
    })(),
  ]);
}

首先,两个单独的分支同时运作。

  • branch 1: Reading in parallel, all at once,
  • branch 2: Reading in serial to force order, but waiting no longer than necessary

这是容易的。

Reading in parallel with a concurrency limit, printing in serial (as early as possible per file).

A "concurrency limit" means that no more than N files will ever being read at the same time.
Like a store that only allows in so many customers at a time (at least during COVID).

第一个辅助职能是:

function bootablePromise(kickMe: () => Promise<any>) {
  let resolve: (value: unknown) => void = () => {};
  const promise = new Promise((res) => { resolve = res; });
  const boot = () => { resolve(kickMe()); };
  return { promise, boot };
}

The function bootablePromise(kickMe:() => Promise<any>) takes a function kickMe as an argument to start a task (in our case readFile) but is not started immediately.

  • promise of type Promise
  • boot of type function ()=>void

promise has two stages in life

  1. Being a promise to start a task
  2. Being a promise complete a task it has already started.

promise transitions from the first to the second state when boot() is called.

async function printFiles4() {
  const files = await getFilePaths();
  const boots: (() => void)[] = [];
  const set: Set<Promise<{ pidx: number }>> = new Set<Promise<any>>();
  const bootableProms = files.map((file,pidx) => {
    const { promise, boot } = bootablePromise(() => fs.readFile(file, "utf8"));
    boots.push(boot);
    set.add(promise.then(() => ({ pidx })));
    return promise;
  });
  const concurLimit = 2;
  await Promise.all([
    (async () => {                                       // branch 1
      let idx = 0;
      boots.slice(0, concurLimit).forEach((b) => { b(); idx++; });
      while (idx<boots.length) {
        const { pidx } = await Promise.race([...set]);
        set.delete([...set][pidx]);
        boots[idx++]();
      }
    })(),
    (async () => {                                       // branch 2
      for (const p of bootableProms) console.log(await p);
    })(),
  ]);
}

以前有两个分支

  • branch 1: For running and handling concurrency.
  • branch 2: For printing

现在的差额不超过<条码>。 许可同时办理。

重要变量是:

  • boots: The array of functions to call to force its corresponding Promise to transition. It is used only in branch 1.
  • set: There are Promises in a random access container so that they can be easily removed once fulfilled. This container is used only in branch 1.
  • bootableProms: These are the same Promises as initially in set, but it is an array not a set, and the array is never changed. It is used only in branch 2.

采用一个模拟<代码>fs.readFile,时间为:

const timeTable = {
  "1": 600,
  "2": 500,
  "3": 400,
  "4": 300,
  "5": 200,
  "6": 100,
};

test run times such as this are seen, showing the concurrency is working --

[1]0--0.601
[2]0--0.502
[3]0.503--0.904
[4]0.608--0.908
[5]0.905--1.105
[6]0.905--1.005

马达加斯加

然而,上述两种解决办法都是Antonio s以较少的代码开展工作的,这就是它如何帮助我从我的数据库中解决数据,从几个不同的儿童数据,然后把数据推到一个阵列,并在做了所有工作之后以承诺的方式解决:

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

同@Bergi的反应一样,但有一个不同之处。

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

<<>PS>/strong>

因此,该法典只能由以下因素设计:三个分离的职能是“纯净”** ,没有副作用,处理整个清单,并易于修改以处理未结案件。

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)

www.un.org/Depts/DGACM/index_spanish.htm 未来的编辑/现状

Node支持高层的等待(这确实有gin,已经赢得,并且可以通过和谐旗帜获得),它冷却,但却没有解决一个问题(从战略上讲,我只处理LTS版本)。 如何获得档案?

Using composition. Given the code, causes to me a sensation that this is inside a module, so, should have a function to do it. If not, you should use an IIFE to wrap the role code into an async function creating simple module that s do all for you, or you can go with the right way, there is, composition.

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

请注意,由于语义原因的变化的名称。 您通过一名校长(一种功能,可由另一功能援引),并找回一个记忆点,其中含有申请逻辑的最初部分。

But, if s not a module and you need to export the logic?

将职能按“合成”职能处理。

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

或改变变数名称,不论......


* by side effect menans any colacteral effect of application that can change the statate/behaviour or introuce bugs in the application, like IO.

** by "pure”, it s in tratrophe since the functions it not organic and the Code can be converged to a organic text, when there s no consoleproduct, only data pors.

除此之外,为了简单起见,你需要与处理副作用、易发生错误的mon合作,并将这一错误与申请分开处理。

目前,Array。 页: 1 每个农业综合企业的财产都不支持“合成”行动,但我们能够创造自己的多功能来满足我们的需要。

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

......

值得注意的是:

  • Your iteratorFunction must be an async function or promise
  • Any arrays created before Array.prototype.<yourAsyncFunc> = <yourAsyncFunc> will not have this feature available

今天 我提出了多方面的解决办法。 追随该星座,等待每个洛普岛的职能。 通过在周围建立总结,我们就可以做到这一点。

可以采取多种方式,其方式如下:

方法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:

利用Promise.all

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

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

方法4:传统 lo或现代 lo

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

了解这种情况会如何产生错误,印刷。 该方法末的标识。

2. 一般性问题:

  • Arbitrary order.
  • printFiles can finish running before printing files.
  • Poor performance.

这些情况并不总是错的,但经常出现在标准使用案件中。

一般说来,除最后一点外,使用每个目标都将产生结果。 它把每个职能称为每个职能,而不必等待其职能的含义,即它把所有职能开始,而不必等待完成。

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

这是土著共同提交文件的一个实例,它将维护秩序,防止职能提前恢复,理论上保持最佳业绩。

这将:

  • Initiate all of the file reads to happen in parallel.
  • Preserve the order via the use of map to map file names to promises to wait for.
  • Wait for each promise in the order defined by the array.

有了这一解决办法,第1个档案一经提供就将立即显示,而不必等到其他文件才能提供。

它还将同时装上所有档案,而不是等到第一件档案开始之前完成。

这和最初版本的唯一回馈是,如果一开始多读,则由于当时可能会发生更多的错误,更难以处理错误。

文本在当时读到档案后,将停止失败,而没有浪费时间试图阅读更多的档案。 即便有一套详细的注销制度,也很难避免在第一份档案中出现故障,但已经阅读了大多数其他档案。

Performance is not always predictable. While many systems will be faster with parallel file reads some will prefer sequential. Some are dynamic and may shift under load, optimisations that offer latency do not always yield good throughput under heavy contention.

这方面也没有错误处理。 如果有些事情要求他们要么成功展示,要么根本不成功,那就失败了。

建议对青.进行深度试验。 每一阶段的标识和假文件为解决办法(总是拖延)。 虽然在简单情况下,许多解决办法似乎都是一样的,但都存在微妙的差别,需要一些额外的审查才能消除。

Use this mock to help tell the difference between solutions:

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

You can use a simple traditional for loop like this

for(let i = 0; i< products.length; i++){
    await <perform some action like database read>
}

Using Task, futurize, and a traversable List, you can simply do

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)

Or perhaps even more functionally oriented

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

If you really wanted more flexibility in encoding, you could just do this (for fun, I m using the proposed Pipe Forward operator )

import { curry, flip } from  ramda 

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

export const readFileUtf8 = readFile( utf-8 )

PS - I don ttries this Code on the console, may have some打字器...... 说到,“带自由的帽子,”90千卡。 iii

正如其他答复提到的那样,你也许希望按顺序执行,而不是同时执行。 Ie. 先提出申请,等到提交文件为止,then<>em>,一经提交第二次档案。 这不会发生。

I think it s important to address why this doesn t happen.

Think about how forEach works. I can t find the source, but I presume it works something like this:

const forEach = (arr, cb) => {
  for (let i = 0; i < arr.length; i++) {
    cb(arr[i]);
  }
};

Now think about what happens when you do something like this:

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

cb(arr[i]),其结尾为logFile(file)。 <代码>logFile功能await 内部,<代码>for 排位将等到<代码>await。 待 处理 i++。

页: 1 简言之,这并非<代码>await <>/code>。 https://developer.mozilla.org/en-US/docs/Web/Javagust/Reference/Operators/await” rel=“nofollow noreferer” The docs:

等待分批执行流量,使 as功能的召集人能够恢复执行。 在等待推迟继续履行会议职能之后,随后执行发言。 如果这一等待是因执行职务而执行的最后表述,则将一名待决的召集人恢复工作,以完成待决的职能,并恢复执行该召集人。

因此,如果你具备以下条件,那么在b>之前就打上了记号:

const delay = (ms) => {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
};

const logNumbers = async () => {
  console.log(1);
  await delay(2000);
  console.log(2);
  await delay(2000);
  console.log(3);
};

const main = () => {
  console.log("a");
  logNumbers();
  console.log("b");
};

main();

转至forEach,forEachlogNumbers> 确实有awaiting和for Each。 仅凭<代码>logFile,就取得了一定进展。

Here is a great example for using async in forEach loop.

Write your own asyncForEach

async function asyncForEach(array, callback) {  
    for (let index = 0; index < array.length; index++) {
        await callback(array[index], index, array)
    }
}

You can use it like this

await asyncForEach(array, async function(item,index,array){
     //await here
   }
)

与Antonio Val s p-iteration相似,替代npm模块是>> > > 编码

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

Alternatively, async-af has a static method (log/logAF) that logs the results of promises:

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

https://async-af.js.org/AsyncAF"rel=“nofollow noreferer”>async-af

如果大家同时对以下所有内容表示厌恶:

async function asyncForEach(arr, fn) {
  await Promise.all(arr.map(fn));
}

如果你不想重复所有内容(例如,如果你的制图功能对所有阵列要素都具有副作用或绘制地图,那么资源成本过高):

备选案文A:允诺

function asyncForEachStrict(arr, fn) {
  return new Promise((resolve) => {
    arr.reduce(
      (promise, cur, idx) => promise
        .then(() => fn(cur, idx, arr)),
      Promise.resolve(),
    ).then(() => resolve());
  });
}

备选案文B:

async function asyncForEachStrict(arr, fn) {
  for (let idx = 0; idx < arr.length; idx += 1) {
    const cur = arr[idx];

    await fn(cur, idx, arr);
  }
}

这并不像OP所要求的那样使用合成/红 the,也不使用<>><>只><>>。 如果你与NodeJS站在后端工作的话。 尽管某些人仍然可能有所助益,因为欧佩组织所举的例子就是要读文件内容,而且通常你会在背后读书。

完全不成体系和不设锁:

const fs = require("fs")
const async = require("async")

const obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"}
const configs = {}

async.forEachOf(obj, (value, key, callback) => {
    fs.readFile(__dirname + value, "utf8", (err, data) => {
        if (err) return callback(err)
        try {
            configs[key] = JSON.parse(data);
        } catch (e) {
            return callback(e)
        }
        callback()
    });
}, err => {
    if (err) console.error(err.message)
    // configs is now a map of JSON data
    doSomethingWith(configs)
})




相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.