[英]Make multiple calls in nodejs
我有一些以下2个URL的模拟数据:
1. Get the list of users from 'https://myapp.com/authors'.
2. Get the list of Books from 'https://myapp.com/books'.
现在我的任务是按名称对Books进行排序,并将排序后的列表作为JSON写入mysortedbooks.json
文件
然后我必须创建一个具有books属性的作者数组,其中包含该作者的所有书籍。
如果作者没有书籍,那么这个数组应该是空的。 此情况不需要排序,数据应作为JSON存储在文件authorBooks.json
中。
现在我必须返回一个在上述步骤完成后解决的承诺。 例如,我应该在下面的代码中返回最后的saveToFile
调用。
const fs = require('fs');
function getFromURL(url) {
switch (url) {
case 'https://myapp.com/authors':
return Promise.resolve([
{ name: "Chinua Achebe", id: "1" },
{ name: "Hans Christian Andersen", id: "2" },
{ name: "Dante Alighieri", id: "3" },
]);
case 'https://myapp.com/books':
return Promise.resolve([
{ name: "Things Fall Apart", authorId: "1" },
{ name: "The Epic Of Gilgamesh", authorId: "1" },
{ name: "Fairy tales", authorId: "2" },
{ name: "The Divine Comedy", authorId: "2" },
{ name: "One Thousand and One Nights", authorId: "1" },
{ name: "Pride and Prejudice", authorId: "2" },
]);
}
}
const outFile = fs.createWriteStream('...out-put-path...');
function saveToFile(fileName, data) {
outFile.write(`${fileName}: ${data}\n`);
return Promise.resolve();
}
function processData() {
const authors = getFromURL('https://myapp.com/authors').then(author => {
return authors;
});
const books = getFromURL('https://myapp.com/authors').then(books => {
return books.sort();
});
return saveToFile('mysortedbooks.json', JSON.stringify(books)).then(() => {
const authorAndBooks = authors.map(author => {
var jsonData = {};
jsonData['name'] = author.name;
jsonData['books'] = [];
for(var i=0; i<books.length; i++) {
if(authod.id == books[i].authorId) {
jsonData['books'].push(books[i].name);
}
}
});
saveToFile('authorBooks.json', authorAndBooks);
});
}
processData().then(() => outFile.end());
我必须实现的主要逻辑是processData
方法。
我尝试添加代码来解决需求,但是在所有操作之后我遇到了如何返回promise
的问题。 另外如何构建我的authorAndBooks
JSON内容。
请帮我解决一下这个。
const authors = getFromURL('https://myapp.com/authors').then(author => {
return authors;
});
const books = getFromURL('https://myapp.com/authors').then(books => {
return books.sort();
});
//authors and books are both promises here, so await them
return Promise.all([authors, books]).then(function(results){
authors = results[0];
books = results[1];
return saveToFile(...);
});
或者声明你的函数async并做
const authors = await getFromURL('https://myapp.com/authors').then(author => {
return authors;
});
const books = await getFromURL('https://myapp.com/authors').then(books => {
return books.sort();
});
return await saveToFile(...);
使用Promise Chaining重构代码并创建多个文件流
const fs = require('fs');
function getFromURL(url) {
switch (url) {
case 'https://myapp.com/authors':
return Promise.resolve([
{ name: "Chinua Achebe", id: "1" },
{ name: "Hans Christian Andersen", id: "2" },
{ name: "Dante Alighieri", id: "3" },
]);
case 'https://myapp.com/books':
return Promise.resolve([
{ name: "Things Fall Apart", authorId: "1" },
{ name: "The Epic Of Gilgamesh", authorId: "1" },
{ name: "Fairy tales", authorId: "2" },
{ name: "The Divine Comedy", authorId: "2" },
{ name: "One Thousand and One Nights", authorId: "1" },
{ name: "Pride and Prejudice", authorId: "2" },
]);
}
}
function saveToFile(fileName, data) {
const outFile = fs.createWriteStream(`/var/${fileName}`);
outFile.write(data);
return Promise.resolve(outFile);
}
function authorBookMapping(data) {
let [authors, books] = data;
var jsonData = {};
authors.map(author => {
jsonData['name'] = author.name;
jsonData['books'] = [];
for(var i=0; i<books.length; i++) {
if(author.id == books[i].authorId) {
jsonData['books'].push(books[i].name);
}
}
});
return {
books: books,
authorAndBooks: jsonData
};
}
function writeFile(data) {
if(data) {
const {books, authorAndBooks} = data;
const book = saveToFile('mysortedbooks.json', JSON.stringify(books));
const author = saveToFile('authorBooks.json', JSON.stringify(authorAndBooks));
return Promise.all([book, author]);
}
}
function processData() {
const authors = getFromURL('https://myapp.com/authors');
const books = getFromURL('https://myapp.com/authors');
return Promise.all([authors, books])
.then(authorBookMapping)
.then(writeFile)
}
processData().then((stream) => {
for(let s in stream) {
stream[s].close();
}
})
.catch((err) => {
console.log("Err :", err);
}) ;
你的代码中有很多错误。 我将尝试逐一解释,阅读代码之间的注释。 我建议你阅读一些文件操作和承诺的基础知识。 问题出在saveToFile方法中,以及如何在processData方法中链接promises。
更改saveToFIle函数,如下所示。 您也可以使用支持fs库的promise,比如fs-extra,但我不确定您是否要使用外部库。
const path = require('path');
const basePath = '.';//whatever base path of your directories
function saveToFile(fileName, data) {
// fs.writeFile method uses callback, you can use many ways to convert a callback method to support promises
// this is one of the simple and doesn't require any libraries to import
return new Promise((resolve,reject)=>{
let filePath = path.join(basePath,fileName);
return fs.writeFile(filePath,data,(err, data)=>{
if(err) reject(err);
else resolve();
});
})
}
现在更改您的processData函数以使用promise.all并以正确的方式对boook进行排序
function processData() {
let books, authors;
//Promise.all can be used when operations are not interdependent, fteches result fasetr as works like parallel requests
return Promise.all([
getFromURL('https://myapp.com/books'),
getFromURL('https://myapp.com/authors')
]).then(data => {
books = data[0];
authors = data[1];
let authorAndBooks = authors.map(author => {
let jsonData = {};
jsonData['name'] = author.name;
jsonData['books'] = [];
for(var i=0; i<books.length; i++) {
if(author.id == books[i].authorId) {
jsonData['books'].push(books[i].name);
}
}
return jsonData;
console.log(jsonData);
});
// you will have to use a comparator to sort objects, given below it will sort books based on names.
books.sort((first,second)=>{ return first.name>second.name ?1:-1})
return Promise.all([
saveToFile("mysortedbooks.json",JSON.stringify(books)),
saveToFile("authorBooks.json",JSON.stringify(authorAndBooks))])
}).then(data=>{
console.log('All operations complete');
})
}
processData();
你有没有考虑过以不同的方式看待这个问题? 如果其他API会出现这种情况,我会考虑在聚合器服务或API本身聚合这些API(如果可以的话)。
最好一次接收所需的所有数据而不是多次呼叫,这将导致延迟和复杂性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.