V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
bramblex
V2EX  ›  JavaScript

[造轮子] 所以为啥后端不能向前端请求数据?

  •  2
     
  •   bramblex · 2016-12-13 14:18:10 +08:00 · 3004 次点击
    这是一个创建于 2903 天前的主题,其中的信息可能已经有所发展或是发生改变。

    造轮子初衷

    前端向后端请求数据从上古时期就不是什么新鲜事,后端向前端推送数据自从有了 socket.io 这种神器以后也没什么大不了的了,那为啥后端为什么不可以向前端那用个类似 Ajax 的东西请求数据?于是我就造了这么个东西 IORequest https://github.com/bramblex/io-request ,不仅能用 socket.io 像 Ajax 一样从前端向后端发送请求,同时也可以从后端向前端发送请求。

    简单例子

    假设我们现在要做一个简单 web 版本的猜拳对战游戏,服务器端的游戏逻辑只需要这样写

    class Game {
    
      constructor (left, right) {
        co(function *() {
          const home_id = next_home_id++
          left.emit(`msg`, `游戏开始,游戏房间号[${home_id}],等待你出拳`)
          right.emit(`msg`, `游戏开始,游戏房间号[${home_id}],等待你出拳`)
          
          // 这里就是向前端请求 choice 方法,并且等待前端的返回
          const [l, r] = yield [
            left.ioRequest({method: 'choice'}),
            right.ioRequest({method: 'choice'})
          ]
    
          // 后端接受到前端的返回后继续游戏的进程
          const _choices = [null, '布', '剪刀', '石头']
          left.emit('msg', `你出的是[${_choices[l]}], 对方出的是[${_choices[r]}]`)
          right.emit('msg', `你出的是[${_choices[r]}], 对方出的是[${_choices[l]}]`)
    
          // 比较并且得出结果
          if (Game.compare(l, r)) {
            left.emit('msg', '你赢了')
            right.emit('msg', '你输了')
          } else {
            right.emit('msg', '你赢了')
            left.emit('msg', '你输了')
          }
    		
          // 游戏结束,关闭链接
          right.disconnect()
          left.disconnect()
    
        })
      }
    }
    

    而前端逻辑更简单了

      // 前端在这里只需要处理后端发送的 choice 请求,并且处理完后通过 response 返回请求的数据
      ioReqClient.handle('choice', ({response}) => {
        const choices = document.getElementById('choices')
        choices.style.display = 'block'
    
        const shi = document.getElementById('shi')
        const jian = document.getElementById('jian')
        const bu = document.getElementById('bu')
    
        // 当按钮被点击的时候
        shi.onclick = () => {
          response(3) // 在这里给后端返回
          choices.style.display = 'none'
          msgLog('我出的是[石头]')
        }
        
        // 同上
        jian.onclick = () => {
          response(2)
          choices.style.display = 'none'
          msgLog('我出的是[剪刀]')
        }
        
        // 同上
        bu.onclick = () => {
          response(1)
          choices.style.display = 'none'
          msgLog('我出的是[布]')
        }
      })
    

    完整例子

    这里是上面那个例子的完整实现。 https://github.com/bramblex/io-request/tree/master/example

    3 条回复    2016-12-15 02:38:34 +08:00
    afpro
        1
    afpro  
       2016-12-13 19:40:11 +08:00
    你想要的是 Wt
    aristotle9
        2
    aristotle9  
       2016-12-13 23:29:42 +08:00
    Reverse Ajax, Part 1: Introduction to Comet
    http://www.ibm.com/developerworks/library/wa-reverseajax1/
    latelx
        3
    latelx  
       2016-12-15 02:38:34 +08:00
    思路不错
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   995 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 19:06 · PVG 03:06 · LAX 11:06 · JFK 14:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.