状态机模式 与 ajax 的结合运用
太神奇了,昨晚做了个梦,梦中我悟出一个道理:凡是涉及到异步操作而且需要返回值的函数,一定要封装成 Promise 的形式,假如返回值取决于多个异步操作的结果,那么需要对每个异步操作进行状态的设计,而且需要封装一个 next 函数。??????,到了晚上才觉到很有意思,所以结合 ajax 设置最短返回时间 和 最大返回时间进行实践:
const PENDING = ‘PENDING‘ const RESOLVED = ‘RESOLVED‘ const REJECTED = ‘REJECTED‘ const FULLFILLED = ‘FULLFILLED‘ /** * @desc 异步操作模拟 * @param time 响应时间 * @param isError 是否抛错 */ const mock = (time, isError) => { return new Promise((resolve, reject) => { setTimeout(() => { if (!isError) { resolve({ user: ‘ManbaX‘ }) } else { reject(‘request error‘) } }, time) }) } /** * @desc 生产不同类型请求的工厂函数 * @param time 响应时间 * @param isError 是否抛错 */ var RequestFactory = function (time, isError) { var request = function () { return new Promise((resolve, reject) => { var min = PENDING var max = PENDING var state = PENDING var res = null var next = function (name) { const cb = function () { if (state === RESOLVED) { resolve(res) } else { reject(res) } } if (name === ‘res‘ && min === FULLFILLED) { cb() } if (name === ‘min‘ && (state === RESOLVED || state === REJECTED)) { cb() } if (name === ‘max‘ && state === PENDING) { reject(‘timeout‘) } } setTimeout(() => { min = FULLFILLED next(‘min‘) }, 500) setTimeout(() => { max = FULLFILLED next(‘max‘) }, 1000) mock(time, isError).then(data => { res = data state = RESOLVED next(‘res‘) }).catch(error => { res = error state = REJECTED next(‘res‘) }) }) } return request } // 不超时, 不返回错误 console.time(‘r1‘) RequestFactory(200)().then(res => { console.log(‘data: ‘, res) }).finally(() => { console.timeEnd(‘r1‘) }) // 不超时, 返回错误 console.time(‘r2‘) RequestFactory(200, true)().catch(err => { console.log(‘error‘, err) }).finally(() => { console.timeEnd(‘r2‘) }) // 超时 console.time(‘r3‘) RequestFactory(2000)().catch(res => { console.log(‘error: ‘, res) }).finally(() => { console.timeEnd(‘r3‘) }) console.time(‘r4‘) RequestFactory(2000)().catch(res => { console.log(‘error: ‘, res) }).finally(() => { console.timeEnd(‘r4‘) })
上面的运行结果符合预期,本来梦中还有另外一个有意思的东西,但是太模糊了就搞忘记了,下次一定早点记录。
相关推荐
kentrl 2020-11-10
结束数据方法的参数,该如何定义?-- 集合为自定义实体类中的结合属性,有几个实体类,改变下标就行了。<input id="add" type="button" value="新增visitor&quo
ajaxyan 2020-11-09
zndy0 2020-11-03
学留痕 2020-09-20
Richardxx 2020-11-09
learningever 2020-09-19
chongxiaocheng 2020-08-16
ajaxhe 2020-08-16
lyqdanang 2020-08-16
curiousL 2020-08-03
TONIYH 2020-07-22
时光如瑾雨微凉 2020-07-19
83510998 2020-07-18
坚持着执着 2020-07-16
jiaguoquan00 2020-07-07
李永毅 2020-07-05
坚持着执着 2020-07-05