#javascript #node.js #express #promise
#javascript #node.js #экспресс #обещание
Вопрос:
Вот мой код, который будет считывать файлы один за другим и отображать их содержимое, и он вернется, как только все файлы будут прочитаны.
Здесь я хочу вызывать api всякий раз, когда 1 файл прочитан полностью
Вот пример содержимого 3 файлов. Не учитывайте, что весь файл будет иметь filenumber.txt . это просто пример
**1.txt**
_____
1-one
1-two
1-three
_____
**2.txt**
_____
2-one
2-two
2-three
_____
**3.txt**
_____
3-one
3-two
3-three
Вот мой маршрутизатор для чтения и отображения всего текста
var express = require('express');
var router = express.Router();
var fs = require('fs');
var arr = [];
router.get('/', function(req, res, next) {
for (let index = 1; index <= 3; index ) {
arr.push(readFile('public/file/' index '.txt'));
console.log(index);
}
Promise.all((arr))
.then(function (results) {
console.log('done!')
res.send('respond with a resource');
});
});
функция чтения файла
function readFile(name){
return fs.readFile(name, "utf8",function(err, data) {
console.log(name,data);
});
}
по обещанию Promise.all((arr))
он вернется, как только все файлы будут прочитаны. Отсюда я хочу вызвать API для каждой строки в файле.
Следующий файл должен быть прочитан только после того, как все вызовы api для текущих файлов будут прочитаны.
Вот функция вызова api
const axios = require('axios');
function doApi(url){
var url = `https://run.mocky.io/v3/url?prod=${url}`
var config = { method : 'get', url : url, headers : {}, data : {}};
return axios(config)
.then(function (response) {
console.log('prod',url,response.data)
}).catch(function(err){
console.log('err1');
})
}
Примечание :
Это должно быть похоже
Шаг 1: Прочитайте первый файл, прочитанные данные будут похожи
1-one
1-two
1-three
Шаг 2: Теперь вызовите do api
// These 3 api's can be ran concurrently, but file read should be done one by one only
https://run.mocky.io/v3/url?prod=${1-one}
https://run.mocky.io/v3/url?prod=${1-two}
https://run.mocky.io/v3/url?prod=${1-three}
Повторите шаг 1 для второго файла.
Как я могу этого добиться
Ответ №1:
Прочитайте каждый файл 1 на 1 в цикле, инициализируя объекты Promise для обработки doApiCall(), передающего содержимое файла (параметр URL) и добавляющего их в массив Promises.
Когда все файлы прочитаны, проблема Promise.all(promises)
.
router.get('/', (req, res) => {
let filepaths = ['filepath1', 'filepath2', '...' , 'filepathN'];
let concurrentAPICalls = [];
for (let fp of filepaths) {
let fileContents = readFileSynchro(fp); // no await
for (let line of fileContents.split('n')) {
// initialise promise to issue REST call with url inside file
concurrentAPICalls.push(new Promise(line).then(doApiCall).catch(apiError)));
}
}
// execute all promises after reading files 1 by 1
// best effort (don't drop remaining on first failure)
Promise.allSettled(concurrentAPICalls).then(() => res.send('all files processed'));
});