Skip to content

Instantly share code, notes, and snippets.

@giscafer
Created May 30, 2019 03:27
Show Gist options
  • Select an option

  • Save giscafer/74d282d5f2cadad9d6bbc4f7ceb755e7 to your computer and use it in GitHub Desktop.

Select an option

Save giscafer/74d282d5f2cadad9d6bbc4f7ceb755e7 to your computer and use it in GitHub Desktop.
前端 对 websocket 封装,提供一个client-js-sdk.js , 使得client可以通过管道发送异步请求。管道只有一个,也就是只有 onMessage 和 emit 。遇到问题就是,socket中 listener 和 emit 是两个独立的块,伪代码说明如何实现封装。
/**
* 伪代码
*/
var socket = {};
socket.on('message', function() {
// listener 真正拿到结果
});
socket.emit({ waybillId: '1zt123213214' }, function() {
// 请求回调,异步接收
});
/**
* 封装client
* 利用事件来包装,一个管道解决send异步拿到结果问题
*/
var client = {};
var ep = new EventProxy(); // 事件代理对象(可自定义事件发送和监听,需要引入eventproxy.js:https://github.com/JacksonTian/eventproxy)
function isFunction(fn) {
return Object.prototype.toString.call(fn) === '[object Function]';
}
var uuid = () => {
return `${Math.random()
.toString(36)
.substr(2)}${Math.random()
.toString(36)
.substr(2)}`;
};
/**
* @params body 参数
* @parmas cb 回调方法
*/
client.prototype.send = function(body, cb) {
if (isFunction(cb)) {
throw new Error('cb is not a function');
}
var msgId = uuid();
// 发送到后端之前,根据msgId自定义监听事件名称,onMessage会自动触发此事件,然后执行cb回调,可以达到异步回调效果
// once 是只监听一次这个事件,执行后自动解绑
ep.once(`ep_message_${msgId}`, function(data) {
cb(data);
});
// websocket 发送数据给后端
socket.emit({ waybillId: '1zt123213214', msgId: msgId }, function() {
// 上边ep.on事件考虑是否可以走这里。发送给后端成功在监听?
});
};
// listener,websocket 监听onMessage 事件,接收管道过来的数据
socket.on('message', function(data) {
var msgId = data.msgId;
// 根据msgId唯一触发执行的事件,并传送数据data
ep.trigger(`ep_message_${msgId}`, data);
});
// 使用效果
client.send({ waybillId: '1zt123213214' }, function(result) {
// 这里就是服务器的result
console.log(result);
});
@giscafer
Copy link
Author

/**
 * 伪代码,ES6改写
 */

let socket = {};

/**
 * 封装client
 * 利用事件来包装,一个管道解决send异步拿到结果问题
 */

const isFunction = fn => {
  return Object.prototype.toString.call(fn) === '[object Function]';
};

const uuid = () => {
  return `${Math.random()
    .toString(36)
    .substr(2)}${Math.random()
    .toString(36)
    .substr(2)}`;
};

// Client 类
class Client {
  constructor() {
    this.ep = new EventProxy();
    this.addListener();
  }
  /**
   * 发送
   * @param {Object} body 参数
   */
  send(body) {
    return new Promise((resolve, reject) => {
      let msgId = uuid();
      // 发送到后端之前,根据msgId自定义监听事件名称,onMessage会自动触发此事件,然后执行cb回调,可以达到异步回调效果
      // once 是只监听一次这个事件,执行后自动解绑
      this.ep.once(`ep_message_${msgId}`, function(data) {
        return resolve(data);
      });

      socket.emit(body);
    });
  }

  addListener() {
    socket.on('message', function(data) {
      let msgId = data.msgId;
      // 根据msgId唯一触发执行的事件,并传送数据data
      this.ep.emit(`ep_message_${msgId}`, data);
    });
  }
}

// =====使用======

let client = new Client();

// 写法1
client.send({ waybillId: '1zt123213214' }).then(result => {
  // 结果
  console.log(result);
  // 业务代码
});

// 同步写法2
async function test() {
  let result;
  try {
    result = await client.send({ waybillId: '1zt123213214' });
  } catch (e) {
    console.log(e);
  }
  // 结果
  console.log(result);
  // 业务代码
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment