ОСУШИТЕ javascript

Я делаю несколько обращений к серверу и создаю страницы и сообщения в формате yaml из API в моем gulpfile. Функции кажутся достаточно похожими, чтобы я мог сделать одну функцию для всех.

Я зацикливаюсь на создании объекта для каждого элемента, поскольку jsonObj не может быть определен вне XMLHttpRequest.

Вот мой код:

function collectLoop(slug, tempDir, destDir, args) {
  const newObject = args;
  fs.writeFile(`${tempDir}${slug}.json`,
  JSON.stringify(newObject), function (err) {
    if (err) throw err;
  });
  gulp.src(`${tempDir}${slug}.json`)
    .pipe(jsonToYaml({ safe: true}))
    .pipe(gulp.dest(destDir));
};


/*********************************************************************/
/******************************* PAGES *******************************/
/*********************************************************************/

function pageCollection(url, tempDir, destDir) {
  const xhr = new XMLHttpRequest();
  xhr.onreadystatechange = () => {
    if (xhr.readyState === 4 && xhr.status === 200) {
      const jsonObj = JSON.parse(xhr.responseText);
      checkDir(tempDir);
      checkDir(destDir);
      for (let i = 0; i < jsonObj.length; i += 1) {
        let hero_heading = false;
        let hero_subheading = false;

        if (jsonObj[i].acf.hero != undefined) {
          hero_heading = jsonObj[i].acf.hero.heading;
          hero_subheading = jsonObj[i].acf.hero.subheading;
        }
        collectLoop(jsonObj[i].slug, tempDir, destDir, {
          "obj_id" : jsonObj[i].id,
          "title" : jsonObj[i].title.rendered,
          "slug" : jsonObj[i].slug,
          "modified" : jsonObj[i].modified,
          "featured_image" : {
            "large" : jsonObj[i]._embedded['wp:featuredmedia'][0].source_url,
            "small" : jsonObj[i]._embedded['wp:featuredmedia'][0].media_details.sizes.thumbnail.source_url,
          },
          "settings" : {
            "contact_box" : jsonObj[i].acf.contact_box,
            "footer_map" : jsonObj[i].acf.map,
            "hero_banner" : jsonObj[i].acf.hero_banner,
          },
          "hero" : {
            "heading" : hero_heading,
            "subheading" : hero_subheading,
          },
          "contact_form" : jsonObj[i].acf.contact_form,
          "excerpt" : jsonObj[i].acf.excerpt,
          "content" : jsonObj[i].content.rendered,
        });
      }
    }
  };
  xhr.open('GET', url);
  xhr.send();
}

/*********************************************************************/
/******************************* POSTS *******************************/
/*********************************************************************/

function postCollection(url, tempDir, destDir) {
  const xhr = new XMLHttpRequest();
  xhr.onreadystatechange = () => {
    if (xhr.readyState === 4 && xhr.status === 200) {
      const jsonObj = JSON.parse(xhr.responseText);
      checkDir(tempDir);
      checkDir(destDir);
      for (let i = 0; i < jsonObj.length; i += 1) {
        collectLoop(jsonObj[i].slug, tempDir, destDir, {
          "obj_id" : jsonObj[i].id,
          "title" : jsonObj[i].title.rendered,
          "slug" : jsonObj[i].slug,
          "date" : jsonObj[i].date,
          "modified" : jsonObj[i].modified,
          "featured_image" : {
            "large" : jsonObj[i]._embedded['wp:featuredmedia'][0].source_url,
            "small" : jsonObj[i]._embedded['wp:featuredmedia'][0].media_details.sizes.thumbnail.source_url,
          },
          "excerpt" : jsonObj[i].excerpt.rendered,
          "content" : jsonObj[i].content.rendered,
        });
      }
    }
  };
  xhr.open('GET', url);
  xhr.send();
}

Добро пожаловать на SO! Вы когда-нибудь пытались объединить эти две функции? Вы где-то застряли?

André DS 21.10.2018 17:46
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
37
1

Ответы 1

Возможно, это следует разместить в https://codereview.stackexchange.com, а не в stackoverflow. Но я все равно попробую на это ответить

Вы можете создать Функции, возвращающие функцию

Вот, наверное, что бы я сделал.

  • используйте fetch вместо XMLHttpRequest
  • используйте async/await, чтобы избежать ада обратного вызова
  • используйте цикл for..of, чтобы постоянно избегать jsonObj[i]
  • используйте Object.assign, чтобы взять объект по умолчанию, который вы делаете во всех запросах, и использовать объект, возвращаемый сопоставлением fn

(PS: не проверено)

function collectLoop(slug, tempDir, destDir, args) {
  const newObject = args
  const file = `${tempDir}${slug}.json`

  fs.writeFile(file, JSON.stringify(newObject), err => {
    if (err) throw err
  })

  gulp.src(file)
    .pipe(jsonToYaml({ safe: true }))
    .pipe(gulp.dest(destDir))
}

// Get is a function that returns another function
const get = (() => {
  async function get (map, url, tempDir, destDir) {
    const res = await fetch(url)
    const jsonObj = await res.json()

    checkDir(tempDir)
    checkDir(destDir)

    for (let item of jsonObj) {
      // Default for everything
      collectLoop(item.slug, tempDir, destDir, Object.assign({
        obj_id: item.id,
        title: item.title.rendered,
        slug: item.slug,
        date: item.date,
        modified: item.modified,
        featured_image: {
          large: item._embedded['wp:featuredmedia'][0].source_url,
          small: item._embedded['wp:featuredmedia'][0].media_details.sizes.thumbnail.source_url,
        },
        excerpt: item.excerpt.rendered,
        content: item.content.rendered
      }, map(jsonObj)))
    }
  }

  return (map = () => {}) => (...args) => get(map, ...args)
})()


const postCollection = get() // no mapping needed, dose the default
const pageCollection = get(item => ({ // This is our mapping fn
  settings: {
    contact_box: item.acf.contact_box,
    footer_map: item.acf.map,
    hero_banner: item.acf.hero_banner,
  },
  hero: {
    heading: item.acf.hero ? item.acf.hero.heading : false,
    subheading: item.acf.hero ? item.acf.hero.subheading : false
  },
  contact_form: item.acf.contact_form
}))

Другие вопросы по теме