我要多次调用服务器,并通过gulpfile中的API以yaml格式创建页面和帖子。这些功能看起来足够相似,我可以为所有这些功能制作一个功能。
我很难为每个项目创建对象,因为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();
}
答案 0 :(得分:0)
这可能应该发布在https://codereview.stackexchange.com中,而不是在stackoverflow上发布。但是我还是要尝试回答这个问题
您可以创建一个Functions that return a function
这可能是我会做的。
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
}))