Возврат разобранного массива JSON асинхронно - PullRequest
1 голос
/ 24 апреля 2020

Я пытаюсь разобрать образец JSON и pu sh отдельные объекты в массив. У меня проблема в том, что я думаю, что это работает, но при вызове console.log для вывода результата, он возвращает значение undefined. Я полагаю, это потому, что я не обрабатываю свои async/await запросы должным образом, но я не уверен, как не запускать функцию console.log, пока все элементы не будут помещены в мой массив.

Атаки. js

//Assume JSON output = {attack source, attack destination, attack type}

//Required modules
//@ts-ignore: undeclared module
//const watchStream = require('fs-watch-stream')
const es = require('event-stream')
var JSONStream = require('JSONStream')
const fs = require('fs');


async function initial(){
    var arr = [];
    var stream = fs.createReadStream('sample.json', {start: 3, encoding: 'utf8'});
    var parser = JSONStream.parse('employees.employee.*');
    stream.pipe(parser);

    parser.on('data', function (obj) {
        arr.push(obj);
    });

    parser.on('finish', async function(arr) {
        return(arr) = await Promise.resolve(arr);
    });
};

initial().then(arr => console.log(arr));

образец. json

{
  "employees": {
    "employee": [
      {
        "id": "1",
        "firstName": "Tom",
        "lastName": "Cruise",
        "photo": "https://jsonformatter.org/img/tom-cruise.jpg"
      },
      {
        "id": "2",
        "firstName": "Maria",
        "lastName": "Sharapova",
        "photo": "https://jsonformatter.org/img/Maria-Sharapova.jpg"
      },
      {
        "id": "3",
        "firstName": "Robert",
        "lastName": "Downey Jr.",
        "photo": "https://jsonformatter.org/img/Robert-Downey-Jr.jpg"
      }
    ]
  }
}

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

Следующий код просто определяет обработчик события; Ваша initial функция не будет ожидать выполнения делегата, не говоря уже о завершении:

parser.on('finish', async function(arr) {
    return(arr) = await Promise.resolve(arr);
});

Вы должны обернуть обработчик в Promise, который может ожидать initial:

await Promise(resolve => parser.on("finish", resolve));
0 голосов
/ 24 апреля 2020

Проблема заключается в этой части:

parser.on('finish', async function(arr) {
  return(arr) = await Promise.resolve(arr);
});

Когда вызывается событие finish, вызывается функция обратного вызова function(arr), но поскольку это функция, любой оператор return внутри он не возвращается initial(), он возвращается function(arr), и ему не присвоено никакой переменной, поэтому значение, возвращаемое в return(arr), теряется. Вы ожидаете, что initial() преобразуется в arr, но поскольку оператор return arr уже находится внутри function(arr), возвращаемое значение теряется и, поскольку initial не имеет никакого оператора return, в конце концов, он разрешается до undefined. Я думаю, что в этом случае проще будет go с классическим c потоком обещаний.

function initial(){
   return new Promise(resolve => {
      var arr = [];
      var stream = fs.createReadStream('sample.json', {start: 3, encoding: 'utf8'});
      var parser = JSONStream.parse('employees.employee.*');
      stream.pipe(parser);

      parser.on('data', function (obj) {
        arr.push(obj);
      });

      parser.on('finish', function(arr) {
        resolve(arr);
      });
   }) 
};

initial().then(arr => console.log(arr));
...