СУХОЙ до JavaScript - PullRequest
       19

СУХОЙ до JavaScript

0 голосов
/ 21 октября 2018

Я делаю несколько звонков на сервер и создаю страницы и сообщения в формате 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();
}

1 Ответ

0 голосов
/ 21 октября 2018

Это может быть опубликовано в 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
}))
...