// ============ imports // ============ exports /** * 给定一个html路径,返回这个htmlPath中所有递归依赖的文件内容 * * 知识点: 在某个层次中,将promise的侵入特性中断掉 * + promise和非promise的衔接点: 回调函数 * + async函数和非async的衔接点: promise */ export const run = (htmlPath, callback) => { fecthRecursive(htmlPath).then(content => { callback(content); }); } // ============ imlements /** * 内容缓冲 * 键:路径 * 值:该文件内容请求的promise */ let cache = new Map(); /** * 模拟文件解析过程,返回该文件静态依赖的其他文件路径 */ const parseDepends = (path, content) => { const depends = { "data/index.html": ["data/b.js", "data/c.js", "data/e.css", "data/f.css"], "data/b.js": ["data/c.js", "data/d.js"], "data/c.js": ["data/d.js"], "data/e.css": ["data/g.png"], "data/f.css": ["data/g.png"], "data/d.js": [], "data/g.png": [], }; return depends[path]; } /** * 获取文件 * 由于返回的是内容,所以需要await */ const fetchFile = async (path) => { let content; if (cache.has(path)) { // 知识点:promise如果已经完成,无论用多少次,都会返回相同的结果(异步) content = await cache.get(path); } else { let p = fetch(path).then(res => res.arrayBuffer()); cache.set(path, p); content = await p; } return content; } /** * 递归处理 */ const fecthRecursive = async (path) => { // 无论如何,都要等内容处理完才能分析依赖 let content = await fetchFile(path); let dependPaths = parseDepends(path, content); let promises = dependPaths.map(elem => { // 知识点:能不能这么写:return await fecthRecursive(elem); return fecthRecursive(elem); }); let childrenContents = await Promise.all(promises); let children = {}; for (let i = 0; i < dependPaths.length; ++i) { let key = dependPaths[i]; let content = childrenContents[i]; children[key] = content; } return { path, content, children, }; }