fs.writeFile的问题,通过提取减少

问题描述 投票:0回答:1

我需要有关正在编写的此帮助程序的帮助。出于某种原因,在readFile上的异步中使用了reduce,当尝试将结果写入文件时,它不会前进到数组的下一项。但是,如果我使用console.log,它就可以正常工作。

const neatCsv = require('neat-csv');
const fetch = require('node-fetch');
const fs = require('fs');

fs.readFile('./codes.csv', async (err, data) => {
    if (err) { throw err; }

    let baseUrl = 'https://hostname/orders?from=2019-10-21T00:00:00.001Z&to=2019-12-31T23:59:59.000Z&promo=';
    const starterPromise = Promise.resolve(null);
    const promos = await neatCsv(data);
    const logger = (item, result) => console.log(item, result);

    function write (item, result) {
        return new Promise((resolve, reject) => {
            fs.writeFile(`./output/${item.PROMO}.json`, JSON.stringify(result), (err) => {
                if (err) { throw err; }
                console.log(`Wrote file ${item.PROMO}`);
            });
        })
    }

    function asyncFetch(item) {
        console.log(`runTask <---------${item.PROMO}---------`);
        return fetch(`${baseUrl}${item.PROMO}`, { headers: { 'x-apikey': 'xyz' }})
            .then(res => (res.json())
            .then(json => json))
    }

    await promos.reduce(
        (p, item) => p.then(() => asyncFetch(item).then(result => write(item, result))),
        starterPromise
    )
});

csv文件只是像这样的基本布局。

PROMO
12345
56789
98765
...

目标是遍历这些,进行REST调用以获取json结果,然后将其写入具有当前促销名称的文件中,然后移至下一个,进行新的调用并将其保存到另一个文件中文件及其相应的代码。

在精简版中,如果您呼叫记录器而不是写入器,则可以正常工作。调用write,它只是反复进行相同的调用并覆盖同一文件,迫使我将其杀死。请帮助,我在这里迷失了方向...

javascript node.js async-await fetch reduce
1个回答
1
投票

[在任何地方使用async函数可能都有更好的时间,fs承诺使用API​​和一个简单的while循环来使用CSV项目。很自然,因为我没有您的CSV或API,所以要进行干式编码。

(您的原始问题可能是由于您没有在resolve函数中使用reject / write,但也不需要减少地狱……)

const neatCsv = require("neat-csv");
const fetch = require("node-fetch");
const fsp = require("fs").promises;

const logger = (item, result) => console.log(item, result);

const baseUrl = "https://hostname/orders?from=2019-10-21T00:00:00.001Z&to=2019-12-31T23:59:59.000Z&promo=";

async function asyncFetch(item) {
  console.log(`runTask <---------${item.PROMO}---------`);
  const res = await fetch(`${baseUrl}${item.PROMO}`, { headers: { "x-apikey": "xyz" } });
  const json = await res.json();
  return json;
}

async function write(item, result) {
  await fsp.writeFile(`./output/${item.PROMO}.json`, JSON.stringify(result));
  console.log(`Wrote file ${item.PROMO}`);
}

async function process() {
  const data = await fsp.readFile("./codes.csv");
  const promos = await neatCsv(data);
  while (promos.length) {
    const item = promos.shift();
    const result = await asyncFetch(item);
    await write(item, result);
  }
}

process().then(() => {
  console.log("done!");
});

使用模拟数据和JSON占位符服务的版本,效果很好:

const fetch = require("node-fetch");
const fsp = require("fs").promises;

const baseUrl = "https://jsonplaceholder.typicode.com/comments/";

async function asyncFetch(item) {
  console.log(`runTask <---------${item.PROMO}---------`);
  const res = await fetch(`${baseUrl}${item.PROMO}`);
  return await res.json();
}

async function write(item, result) {
  const data = JSON.stringify(result);
  await fsp.writeFile(`./output/${item.PROMO}.json`, data);
  console.log(`Wrote file ${item.PROMO}: ${data}`);
}

async function getItemList() {
  return [
    {PROMO: '193'},
    {PROMO: '197'},
    {PROMO: '256'},
   ];
}

async function process() {
  const promos = await getItemList();
  while (promos.length) {
    const item = promos.shift();
    const result = await asyncFetch(item);
    await write(item, result);
  }
}

process().then(() => {
  console.log("done!");
});
© www.soinside.com 2019 - 2024. All rights reserved.