Как я могу создать вложенный цикл For для ввода данных в мой javascript-код Nightmare

У меня есть два файла JSON. Я хочу сравнить объекты JSON в обоих файлах; json1 и json2. Если в массиве первого файла json (json1) есть объект, которого нет во втором файле json (json2), я хотел бы передать его через приведенный ниже код Nightmare js, а затем передать объект во второй файл json, используя .push().


JS-КОД:

var Nightmare = require('nightmare');
var nightmare = Nightmare({
  show: true
});
var json1 = require('./json1.json')
var json2 = require('./json2.json')

for (var i = 0; i < json1.length; i++) {
  for (var c = 0; c < json2.length; c++) {
    if (json1[i] !== (json2[c])) {
      console.log(json1[i])
      return nightmare
        .goto(json1[0].searchOn)
        .insert('.gLFyf', json1[0].searchText)
        .wait(3000)
        .end()
        .evaluate((json2, json1) => {
          return json2[c].push(json1[i])
        }, json2, json1)
        .then()
    } else {
      console.log('End!')
    }
  }
}

Данные JSON1

[
    {
        "searchOn": "https://www.google.com",
        "searchText": "I love google"
    },
    {
        "searchOn": "https://www.google.com",
        "searchText": "I'm hungry, where can I eat?'"
    }
]

Данные JSON2

[
    {
        "searchOn": "https://www.google.com",
        "searchText": "What's the date?"
    },
    {
        "searchOn": "https://www.google.com",
        "searchText": "What is the internet"
    },
    {
        "searchOn": "https://www.google.com",
        "searchText": "What's the weather like today?"
    }
]

Однако код Js дает мне эту ошибку: UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'push' of undefined.

Код также не выполняет кошмарный js-код для всех объектов в цикле (выполняет задачу только для первого элемента.

Посоветуйте, как мне исправить эти ошибки.

С уважением.


person Leon Peter    schedule 26.12.2018    source источник


Ответы (2)


Вы не можете перебирать объект по индексам. Это будет работать с массивами, которые представляют собой тип объекта с ключами, сопоставленными с индексами, начинающимися с 0. Если вы хотите выполнить итерацию по любому объекту, используйте Object.keys или оператор for-in. Вы можете узнать, как сделать оба здесь.

То же самое относится и к push, который представляет собой метод массива

person Tomer Sharon    schedule 26.12.2018

Взаимодействие между несколькими ошибками кода может быть трудно предсказать и/или объяснить. Вот несколько для обзора:

  1. if (json1[i] !== (json2[c]))

Записи в json1 и json2 — это объекты, созданные JSON.parse. Это всегда разные объекты. Сравнение равенства значений их примитивных свойств потребуется, чтобы увидеть, содержат ли объекты одни и те же данные.

  1. return nightmare ...

Это синхронно вернет ожидающее обещание, возвращенное then() в конце цепочки обещаний из функции, в которой выполняется этот код, поэтому выполняется только первая итерация цикла. Для завершения цикла необходимо удалить ключевое слово return.

  1. json2[c].push(json1[i] в одном из обратных вызовов

имеет две проблемы:

а) выполняется асинхронно. Если return удаляется и цикл завершается, c и i равны длине json2 и json соответственно и возвращают неопределенное значение, если используются в качестве индексов массива. Это проблема асинхронного программирования — см. закрытие JavaScript внутри циклов — простой практический пример для решения.

б) json2[c] — это простой объект, а не массив, поэтому у него нет метода push. Вероятно, вы хотели поместить значение в конец json2, а не в запись в нем.

  1. В цепочке обещаний кошмаров нет пункта catch. Неперехваченные ошибки отклонения обещаний могут стать фатальными в будущем.

Примечание. У меня нет точной причины, по которой json2[c] не определено в фрагменте кода - вы цитируете фактический код, а не опубликованный урезанный пример? Я бы также предложил изучить асинхронные функции и оператор await как средство зацикливания асинхронных операций.

person traktor    schedule 26.12.2018