采用了异步Promise写法:
<code class="language-javascript">//tag generator var tg = (name,content,props)=>`<${name} ${props||''}${content?'':' '}>${content||''}${content?'':''}` var htmlWrap = (content)=>tg('html',tg('body',content)) var textInput = (name)=>tg('input',null,'name="'+name+'" type="text"') var submit = tg('input',null,'type="submit"') //form generator var fg = (content)=>tg('form',content,'action="" method="post"') var formHTML = (content)=>htmlWrap(fg(content)) var linkHTML = (address)=>htmlWrap(tg('a','请点这里','href="'+address+'"')) var textHTML = (text)=>htmlWrap(text) var ee = (require('events').EventEmitter); var nextVisitPromise = function(){ var nvp = {} var e = new ee; nvp.trig = (req,res)=>{ e.emit('trig',{req,res,waitForNextVisit:nvp.waitForNextVisit}) } nvp.waitForNextVisit = ()=>{ return new Promise((resolve,reject)=>{ e.on('trig',resolve) }) } return nvp } var nvprecords = {} var bindOp = (path,op)=>{ app.all(path,(req,res)=>{ var s = req.session var key = 'p'+path if(s[key]){ console.log(s[key]); var nvp = nvprecords[s.id] nvp.trig(req,res) }else{ s[key] = true var nvp = nextVisitPromise() nvprecords[s.id]=nvp nvp.waitForNextVisit() .then((ctx)=>{ return op(ctx) }) .then(()=>{ console.log('clearing session...'); req.session.destroy() nvprecords[s.id]=undefined }) nvp.trig(req,res) } }) } app.listen(9001,()=>{console.log('listening on 9001');}); bindOp('/abc',(ctx)=>{ var userinput ctx.res.send(formHTML(textInput('cde')+submit)) return ctx.waitForNextVisit() .then(ctx=>{ userinput = ctx.req.body.cde ctx.res.send(linkHTML('/abc')) return ctx.waitForNextVisit() }) .then(ctx=>{ ctx.res.send(textHTML(userinput||'....')) }) }) </${name}></code>
上面这段代码,访问/abc
路径后,效果符合题目要求。
每次向用户返回HTML之后,直接Promise等待用户下一次访问,并通过闭包使用userinput
变量。使用这种设计,就可以很短的代码,设计任意复杂的跳转流程,而不需要使用大量的路径以及状态机。
坏处:相当于把HTTP硬生生地变成了有状态协议,宕机的时候状态会丢失
好处:写起来无负担
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |