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



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

  1. 读取文件
  2. 将文件内容发送到 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) {
.....
)};

}

您可以通过不同的方式实现您正在尝试做的事情。

使用承诺作为回报

fs.readfile(dir + filename, 'utf8',function(err, fileContent){
if(err) throw err;
return anotherAsyncServiceCall(fileContent);
}).then(function(err, response){
if(err) throw err;
//return the response or do any thing
}).catch(function(exception){
console.log('exception occured',exception);
});

列出所有承诺,然后使用 Promise.all(( 一次执行它们

//creating a global variable to contain our promises
var promiseList =[];
filenames.forEach(function (filename) {
var fileContent=  fs.readFileSync(dir + filename, 'utf8');
promiseList.push(anotherAsyncServiceCall(fileContent));         
});

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

Promise.all(promiseList).then(function(err,response) {
console.log(response);
});

使用异步 - 等待

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

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

使函数成为async函数,并将await设置为异步任务。

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获取响应。

最新更新