前言
距离上次的文章过了1个多月,我们今天来继续优化和更新需求。
- 微信小程序由于审核机制,如果每次需要更新数据的话,就需要重新提交审核和修改,我们能不能吧数据保存到外部,通过修改外部数据达到更新小程序的目的。
- 由于每次换章节都重新请求一个全新的文件,我们是否可以缓存到本地,减少用户请求次数。
针对第一个请求
我们一开始是使用一个js文件
进行保存数据的,所以我们对程序内部只是暴露一个数据接口,所以后期修改也比较快速。
所以在初期程序设计的时候,是要考虑到后期迭代更新的需求变化,所以一个好的代码不仅仅是能够运行,还需要能够更方便地更新功能需求。
我们不在使用这个来保存数据,而是通过发送求请求获取数据接口。
我们来看看如何实现。
我们在导入数据的接口进行修改
var directoryList_js_1 = require("../../utils/directoryList.js");
在修改前,我们需要注意在哪里开始发送请求数据?
由于我们是文章类型,所以最好在用户请求前就获取到所有文章列表数据信息。我们就放在加载的时候获取到文章目录。
然后通过localStorage
来进行传递数据信息。
我们在index.js
文件中的onload
事件进行加载。
由于是异步的,我们使用promise来封装请求
const promiseRequset = function (url){
return new Promise((res, rej) => {
wx.request({
url: url,
success:res,
fail:rej
})
})
}
//...index onload事件
onload:()=>{
promiseRequset('http').then((res)=>{
let data = res.data.str
wx.setStorageSync('diction', data)
},rej=>{
wx.showModal({
title: '服务器错误',
content: '请稍后再来访问',
})
})
}
将请求的数据保存到本地缓存
在浏览网页修改,直接读取本地缓存,而不是读取原本JS文件数据
由于localStorage
使用的是字符串保存,所以需要使用JSON.parse()
进行转换,这个时候需要转换2次,具体原因可能是微信小程序的API只是解析第一层就停止了,所以需要手动的重新解析一次。
let dictionData = wx.getStorageSync('diction')
directoryList_js_1 = JSON.parse(dictionData)
if (typeof directoryList_js_1 === 'string') {
directoryList_js_1 = JSON.parse(directoryList_js_1)
}
由于后面都是读取JSON格式的数据,所以优化已经完成,能够正常的执行。
第二个需求
我们看看原本读取Markdown的代码
requireData= function (url, index) {
var _ts = this;
wx.request({
url: url,
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success: (res) => {
// 保存到本地
var pattern = /\s##\s/
var _ts = res._ts
var index = res.index
res = res.res
// 以## 分页
let allArticle = res.data.split(pattern)
for (var _index in allArticle) {
if (_index === 0 || _index === '0') {
} else {
allArticle[_index] = `## ${allArticle[_index]}`
}
}
var allArticleLength = allArticle.length
// 显示第一页内容
var data = app.towxml.toJson(allArticle[0], 'markdown');
data = app.towxml.initData(data, {
app: _ts
});
data.theme = 'light';
if (_ts.data.show) {
_ts.setData({
article: data,
// 开始阅读 显示文章内容
startRead: false,
// 目录的高亮index
readnow: index,
// 目录显示
// 每一章的页面内容
allArticleLength: allArticleLength,
allArticle: allArticle,
// 每一章从第一页开始读
characterIndex: 0
});
} else {
var animation = wx.createAnimation({
duration: 1000,
timingFunction: 'ease'
});
let xChange = 500 / 750 * wx.getSystemInfoSync().windowWidth
animation.translate(-xChange, 0).step()
_ts.setData({
article: data,
// 开始阅读 显示文章内容
startRead: false,
// 目录的高亮index
readnow: index,
// 目录显示
show: true,
ani1: animation,
// 每一章的页面内容
allArticleLength: allArticleLength,
allArticle: allArticle,
// 每一章从第一页开始读
characterIndex: 0
});
}
wx.pageScrollTo({
scrollTop: 0
})
wx.hideLoading()
}
});
}
可以看见初版是一个赶工的代码,所以我们来进行优化。
我们知道请求前就需要判断一次本地是否缓存Markdown文件,Markdown文件本身也是字符串的数据,所以我们同样可以使用localStorage
进行保存。
如果本地缓存了文件,则直接获取数据进行解析,没有缓存就进行请求Markdown文件,请求成功后保存到本地。
我们可以初步写出逻辑代码:
requireData= function (url, index) {
var _ts = this;
// 缓存判断 使用promise异步请求
storageManager(url).then((res)=>{
handleMarkdown({ res, _ts, index })
},(res)=>{
requsetMarkdown(_ts, url, index)
})
}
缓存读取代码:
function storageManager(url) {
return new Promise((resolve, rej)=>{
wx.getStorage({
key: url,
success: (res) => {
console.log(res)
if (res.errMsg ==='getStorage:ok') {
resolve(res.data)// 读取缓存数据 进行解析
}else {
rej()// 进行网络请求
}
}, fail: rej// 缓存出错 进行网络请求
})
})
}
返回一个promise对象,我们就可以清晰地设置执行代码:如果失败则执行网络请求,如果成功则直接解析。
我们先来写成功解析的代码,只需要把之前写好的解析顺序进行提取封装即可。
function handleMarkdown(res){
var pattern = /\s##\s/
var _ts = res._ts
var index = res.index
res = res.res
// 以## 分页
let allArticle = res.data.split(pattern)
for (var _index in allArticle) {
if (_index === 0 || _index === '0') {
} else {
allArticle[_index] = `## ${allArticle[_index]}`
}
}
var allArticleLength = allArticle.length
// 显示第一页内容
var data = app.towxml.toJson(allArticle[0], 'markdown');
data = app.towxml.initData(data, {
app: _ts
});
data.theme = 'light';
if (_ts.data.show) {
_ts.setData({
article: data,
// 开始阅读 显示文章内容
startRead: false,
// 目录的高亮index
readnow: index,
// 目录显示
// 每一章的页面内容
allArticleLength: allArticleLength,
allArticle: allArticle,
// 每一章从第一页开始读
characterIndex: 0
});
} else {
var animation = wx.createAnimation({
duration: 1000,
timingFunction: 'ease'
});
let xChange = 500 / 750 * wx.getSystemInfoSync().windowWidth
animation.translate(-xChange, 0).step()
_ts.setData({
article: data,
// 开始阅读 显示文章内容
startRead: false,
// 目录的高亮index
readnow: index,
// 目录显示
show: true,
ani1: animation,
// 每一章的页面内容
allArticleLength: allArticleLength,
allArticle: allArticle,
// 每一章从第一页开始读
characterIndex: 0
});
}
wx.pageScrollTo({
scrollTop: 0
})
}
这样网络请求也不需要解析代码了,直接调用上面的解析函数即可。
网络请求也是异步的,也是用promise来实现。
function requsetMarkdown(_ts, url, index){
new Promise((resolve,rej)=>{
wx.request({
url: url,
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success: (res) => {
// 保存到本地
wx.setStorageSync(url, res)
resolve({ res, _ts,index})
}
});
}).then((res)=>{
// 直接解析Markdown文件
handleMarkdown(res)
setTimeout(() => {
wx.hideLoading()
}, 1000)
})
}
好了全部已经完成,功能其实并不复杂,从这个例子可以看出代码耦合性的问题,如果耦合性太高就无法进行功能增加,极端一点就可以需要重构代码,耦合性处理的恰当我们就可以快速地将一些复用的代码进行提取封装,如处理markdown文件的函数,不过是否使用请求还是缓存的数据,执行的过程都是一样的,所以可以进行复用封装。