Javascript 在两个任务之间添加延迟并获得意外的执行顺序

Javascript 在两个任务之间添加延迟并获得意外的执行顺序,javascript,Javascript,我有一个循环。我在循环中执行以下任务 读取文件 将文件内容发送到web服务并获取响应 由于web服务速度缓慢,我需要在这两个任务之间添加一个延迟。我在这两个任务之间使用setTimeout。问题是每个任务的执行顺序。当我记录每个任务的输出时,我可以看到它首先打印从文件读取的所有文件内容,然后是“延迟”消息(n次),然后是服务调用的响应。根据控制台输出 [File 1 content] [File 2 content] [File 3 content] Delayed Delayed Delaye

我有一个循环。我在循环中执行以下任务

  • 读取文件
  • 将文件内容发送到web服务并获取响应
  • 由于web服务速度缓慢,我需要在这两个任务之间添加一个延迟。我在这两个任务之间使用
    setTimeout
    。问题是每个任务的执行顺序。当我记录每个任务的输出时,我可以看到它首先打印从文件读取的所有文件内容,然后是“延迟”消息(n次),然后是服务调用的响应。根据控制台输出

    [File 1 content]
    [File 2 content]
    [File 3 content]
    Delayed
    Delayed
    Delayed
    [Service response for File1]
    [Service response for File2]
    [Service response for File3]
    
    这三个任务似乎是并行执行的,但不是顺序执行的。我的目标是按顺序执行它们

    我的代码中导致上述行为的问题是什么

    下面是我的代码

    function myFunction() {
        console.log("Delayed");
    }
    
    filenames.forEach(function (filename) {
    
      fs.readFile(dir + filename, 'utf8', function(err, fileContent) {
    
         console.log(fileContent);
    
         setTimeout(myFunction, 3000);
    
    
         anotherAsyncServiceCall(fileContent, function (err, response) {
        .....
        )};
    

    }

    将您的函数设置为
    异步
    函数,并将
    等待
    设置为异步任务

    function myFunction() {
      console.log("Delayed");
    }
    
    let contents = [];
    let responses = [];
    
    const fileReading = async (filename) => {
      const content = await fs.readFileSync(dir + filename, 'utf8');
      contents.push(content);
    }
    
    const getResponse = async (content) => {
      const response = await anotherAsyncServiceCall(content);
      responses.push(response);
    }
    
    filenames.forEach(async function(filename) {
      await fileReading(filename);
    });
    
    
    contents.forEach(async function(content) {
      await getResponse(content);
    });
    

    您可以从
    响应
    数组中获取响应。

    将您的函数设置为
    异步
    函数,并将
    等待
    设置为异步任务

    function myFunction() {
      console.log("Delayed");
    }
    
    let contents = [];
    let responses = [];
    
    const fileReading = async (filename) => {
      const content = await fs.readFileSync(dir + filename, 'utf8');
      contents.push(content);
    }
    
    const getResponse = async (content) => {
      const response = await anotherAsyncServiceCall(content);
      responses.push(response);
    }
    
    filenames.forEach(async function(filename) {
      await fileReading(filename);
    });
    
    
    contents.forEach(async function(content) {
      await getResponse(content);
    });
    

    您可以从
    responses
    数组中获取您的响应。

    您可以通过不同的方式实现您想要做的事情

    使用承诺作为回报

    列出所有承诺,然后使用promise.all()立即执行所有承诺。

    然后使用
    Promise.all()
    执行所有承诺:

    Promise.all(promiseList).then(function(err,response) {
         console.log(response);
    });
    
    使用异步-等待

    更新fs.readFile不是承诺,而是异步的,因此它支持回调


    你可以通过不同的方式实现你想做的事情

    使用承诺作为回报

    列出所有承诺,然后使用promise.all()立即执行所有承诺。

    然后使用
    Promise.all()
    执行所有承诺:

    Promise.all(promiseList).then(function(err,response) {
         console.log(response);
    });
    
    使用异步-等待

    更新fs.readFile不是承诺,而是异步的,因此它支持回调



    默认情况下,
    fs.readFile
    是异步的,因此您应该使用同步读取器:
    fs.readFileSync
    setTimeout
    不会暂停当前线程。它只是添加了一个待以后运行的任务。您可以使用
    promises
    调用web服务,然后在foreach循环中从中调用
    。然后()。您可以显示一个代码片段来执行此操作吗默认情况下,
    fs.readFile
    是异步的,因此您应该使用同步读取器:
    fs.readFileSync
    setTimeout
    不会暂停当前线程。它只是添加了一个待以后运行的任务。您可以使用
    promises
    调用web服务,然后在foreach循环中从中调用
    。然后()。你能给我看一段代码吗?我用上面的代码试过了。它读取文件,但不将任何内容推入内容。因此,第二个循环永远不会执行。原因是什么that@Malintha我已经编辑了代码。你能检查一下这个吗。如果你仍然有一个问题,我有另一种方法。我试着用上面的代码。它读取文件,但不将任何内容推入内容。因此,第二个循环永远不会执行。原因是什么that@Malintha我已经编辑了代码。你能检查一下这个吗。如果你还有问题,我有另一种方法。非常感谢你的回答。我试了第二种方法。我得到错误
    fs.readFile(dir+filename,'utf8')。然后(函数(err,shapeFileContent){^TypeError:无法读取未定义的
    @Malintha的属性'then',我已经更新了答案,请检查,我使用了
    fs.readFile
    作为承诺,而它需要一个
    回调
    。我尝试了第二种方法,但我从承诺中只得到一个“未定义”响应。all(),在承诺列表中似乎只有一个项目,而且
    响应
    也未定义。没有将项目推入数组的原因是什么。执行顺序是否有问题?似乎是
    承诺.all()
    在将所有项放入数组之前执行。@Malintha不,它实际上不会在文件名(如果使用了
    fs.readFileSync
    )的循环完成后执行,对于无法在数组中推送的项,它将根据语法
    Promise.all(promiseArray)执行
    输入基本上是一个承诺的
    数组。因此,如果它不是承诺数组,它可能会给你
    未定义的
    。非常感谢你的回答。我尝试了第二种方法。我得到错误
    fs.readFile(dir+filename,'utf8')。然后(函数(err,shapeFileContent){^TypeError:无法读取未定义的
    @Malintha的属性'then',我已经更新了答案,请检查,我使用了
    fs.readFile
    作为承诺,而它需要一个
    回调
    。我尝试了第二种方法,但我从承诺中只得到一个“未定义”响应。all(),在承诺列表中似乎只有一个项目,而且
    响应
    也未定义。没有将项目推入数组的原因是什么。执行顺序是否有问题?似乎是
    承诺.all()
    在将所有项放入数组之前执行。@Malintha不,它实际上不会在文件名(如果使用了
    fs.readFileSync
    )的循环完成后执行,对于无法在数组中推送的项,它将根据语法
    Promise.all(promiseArray)执行
    输入基本上是承诺的
    数组
    。因此,如果它不是承诺数组,它可能会为您提供
    未定义的
    fs.readfile(dir + filename, 'utf8',async function(err, fileContent){
     if(err) throw err;
     var response =  await anotherAsyncServiceCall(fileContent);
     return response;
    }).catch(function(exception){
      console.log('exception occured',exception);
    });