简体   繁体   English

如何在for循环中使用回调或异步?

[英]How to use callback or Async in for loop?

I search and read about Asynchronous functions and callbacks. 我搜索并阅读了有关异步函数和回调的信息。 But i was not able to solve my problem for a week. 但是我有一个星期无法解决我的问题。 I want to do 'fs readfile' inside loop with order. 我想按顺序在循环内执行“ fs readfile”。 I try the following but i am not successful. 我尝试以下方法,但不成功。

// on the code below, console.log print the value in random order and 'storedata' is empity.
// my goal is to do readfile in loop orderly and store the value

router.get("/files/readfiles", function(req,res){
  var storedata= []; 
  var filenames= ["file1","file2","file3","file4"]; 

  for (var i=0; i< filenames.length; i++){      
    fs.readFile('views/allfiles/'+ filenames[i] +'.ejs','utf8',function (err, data) {
      if (err) throw err;  
      storedata.push(data);         
      console.log(data);         
    });
    console.log(storedata); // this returns empty array
  });

I also try in another way: 我也尝试另一种方式:

router.get("/files/readfiles", function(req,res){
var filenames= ["file1","file2","file3","file4"];   

filenames.forEach(readfiles);

function readfiles(value) {
  var dataread =  fs.readFile('views/allfiles/'+ value +'.ejs','utf8')

    console.log (dataread);
   }
});

on the above try i get an error of: TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. 在上面的尝试中,我收到以下错误:TypeError [ERR_INVALID_CALLBACK]:回调必须是一个函数。

I am new to Asynchronous methods any help please. 我对异步方法是新手,请帮忙。

If you're using Node v10 or above you can use the fs promises API and async/await. 如果您使用的是Node v10或更高版本,则可以使用fs promises API和async / await。

To read the files in series: 要读取系列文件:

router.get( "/files/readfiles", async function( req, res ) {
  const storedata = [ ]; 
  const filenames = [ "file1", "file2" , "file3", "file4" ]; 

  for (let i = 0; i < filenames.length; i++ ) {      
    const data = await fs.promises.readFile( 'views/allfiles/'+ filenames[i] +'.ejs', { encoding: 'utf8' } ); 
    storedata.push( data );         
  }

  console.log( storedata ); 

} );

or to read them in parallel: 或并行阅读它们:

router.get( "/files/readfiles", async function( req, res ) {
  const promises = [ ]; 
  const filenames = [ "file1", "file2", "file3", "file4" ]; 

  for (let i = 0; i < filenames.length; i++ ) {      
    const promise = fs.promises.readFile( 'views/allfiles/'+ filenames[i] +'.ejs', { encoding: 'utf8' } ); 
    promises.push( promise );         
  }

  const storedata = await Promise.all( promises );

  console.log( storedata ); 

} );

You should use ES2017 async/await syntax like this. 您应该像这样使用ES2017 async/await语法。

router.get("/files/readfiles", async function(req, res){
  var storedata= []; 
  var filenames= ["file1","file2","file3","file4"]; 

  for (var i=0; i< filenames.length; i++){  
    await new Promise((resolve, reject) => {    
        fs.readFile('views/allfiles/'+ filenames[i] +'.ejs','utf8',function (err, data) {
          if (err) return reject( err )
          storedata.push(data);
          resolve();               
        });
    })
    console.log(storedata);
  }
});

Your second code doesnt provide a callback function, thats your error. 您的第二个代码不提供回调函数,这就是您的错误。

Your first code, you are trying to work with callbacks, so you'll need to follow your code nested into the callback, thats what is called callback hell 您的第一个代码,您正在尝试使用回调,因此您需要遵循嵌套在回调中的代码,这就是所谓的回调地狱

It would look like this: 它看起来像这样:

router.get("/files/readfiles", function(req,res){
  var storedata= []; 
  var filenames= ["file1","file2","file3","file4"]; 

  for (let i = 0; i< filenames.length; i++){      
    fs.readFile('views/allfiles/'+ filenames[i] +'.ejs','utf8',function (err, data) {
      if (err) throw err;  
      storedata[i] = data;

      if (storedata.length === filenames.length) {
        console.log(storedata);
        // do stuff you want, like:
        res.send(storedata)
      }            
     });
  });

If you plan on using node 10, I recommend you look at the other answer with Promise.all. 如果计划使用节点10,建议您使用Promise.all查看其他答案。 Async/await is great 异步/等待很棒

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM