Anguer

Anguer 查看完整档案

北京编辑  |  填写毕业院校某互联网公司  |  js 编辑 anguer.com 编辑
编辑

js

个人动态

Anguer 关注了标签 · 2020-02-10

flutter

clipboard.png

Flutter 是 Google 用以帮助开发者在 iOS 和 Android 两个平台开发高质量原生 UI 的移动 SDK。

Flutter is Google’s mobile app SDK for crafting high-quality native interfaces on iOS and Android in record time. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source.

Flutter 官网:https://flutter.dev/
Flutter 中文资源:https://flutter-io.cn/
Flutter Github:https://github.com/flutter/fl...

关注 1016

Anguer 收藏了文章 · 2019-07-23

vue中使用第三方UI库的移动端rem适配方案

需求:使用vue-cli脚手架搭建项目,并且使用第三方的UI库(比如vant,mint ui)的时候,因为第三方库用的都是用px单位,无法使用rem适配不同设备的屏幕。

解决办法:使用px2rem-loader插件将第三方ui库的px转换成rem单位。

(1) npm install px2rem-loader --save-dev 安装插件
(2)然后在vue-cli项目找到built/utils文件,在里面加上以下代码:

var px2remLoader = {
  loader: 'px2rem-loader',
  options: {
    remUnit: 75     // (这里是指设计稿的宽度为 750 / 10)
  }
}

然后在generateLoaders函数里面插入px2remLoader ,再重启 npm run dev服务即可。

clipboard.png

(3)把px转换成rem的配置完成后,还需要在入口文件(main.js)里面配置一段代码,此代码的目的是监听window窗口大小的变化,从而动态改变html根节点的font-size的大小。达到适配不同设备的效果;(注意:不知道为什么要动态改变html根节点的font-size的话,建议去看一下rem的知识)

window.onresize = setHtmlFontSize;
function setHtmlFontSize(){
    const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth;
    const htmlDom = document.getElementsByTagName('html')[0];
    htmlDom.style.fontSize = htmlWidth / 10 + 'px';
};
setHtmlFontSize();

上面代码是为了当第一次加载main.js的时候就设置根节点的(html节点)font-size。否则会出现混乱页面。

clipboard.png

查看原文

Anguer 提出了问题 · 2018-08-31

关于Pomelo客户端使用Node.js, WebSocket的问题

  1. 依赖包

    • ws: "0.8.0"
  2. 代码
var WebSocket = require('ws')
var Protocol = require('pomelo-protocol')
var Package = Protocol.Package
var Message = Protocol.Message
var EventEmitter = require('events').EventEmitter
var protobuf = require('pomelo-protobuf')
var util = require('util')
var JS_WS_CLIENT_TYPE = 'js-websocket'
var JS_WS_CLIENT_VERSION = '0.0.1'

var heartbeatInterval_const = 5000
var nextHeartbeatTimeout_const = 0
var gapThreshold_const = 100 // heartbeat gap threshold
var RES_OK = 200
var RES_OLD_CLIENT = 501

var pomelo = function () {
  this.socket = null
  this.reqId = 0
  this.callbacks = {}
  this.handlers = {}
  this.routeMap = {}
  this.heartbeatInterval = heartbeatInterval_const
  this.heartbeatTimeout = heartbeatInterval_const * 2
  this.nextHeartbeatTimeout = nextHeartbeatTimeout_const
  this.gapThreshold = gapThreshold_const // heartbeat gap threshold
  this.heartbeatId = null
  this.heartbeatTimeoutId = null
  this.handshakeCallback = null
  initPomleo(this)
  this.handshakeBuffer = {
    'sys': {
      type: JS_WS_CLIENT_TYPE,
      version: JS_WS_CLIENT_VERSION
    },
    'user': {}
  }
}

util.inherits(pomelo, EventEmitter)
pomelo.prototype.init = function (params, cb) {
  this.params = params
  params.debug = true
  this.initCallback = cb
  var host = params.host
  var port = params.port

  var url = 'ws://' + host
  if (port) {
    url += ':' + port
  }

  if (!params.type) {
    this.handshakeBuffer.user = params.user
    this.handshakeCallback = params.handshakeCallback
    this.initWebSocket(url, cb)
  }
}

pomelo.prototype.onData = function (self, data) {
  //probuff decode
  var msg = Message.decode(data)

  if (msg.id > 0) {
    msg.route = self.routeMap[msg.id]
    delete self.routeMap[msg.id]
    if (!msg.route) {
      return
    }
  }
  msg.body = deCompose(self, msg)
  processMessage(self, msg)
}

var processMessage = function (pomelo, msg) {
  if (!msg || !msg.id) {
    // server push message
    // console.error('processMessage error!!!');
    pomelo.emit(msg.route, msg.body)
    return
  }

  //if have a id then find the callback function with the request
  var cb = pomelo.callbacks[msg.id]

  delete pomelo.callbacks[msg.id]
  if (typeof cb !== 'function') {
    return
  }

  cb(msg.body)
  return
}

var deCompose = function (pomelo, msg) {
  var protos = !!pomelo.data.protos ? pomelo.data.protos.server : {}
  var abbrs = pomelo.data.abbrs
  var route = msg.route

  try {
    //Decompose route from dict
    if (msg.compressRoute) {
      if (!abbrs[route]) {
        return {}
      }

      route = msg.route = abbrs[route]
    }
    if (!!protos[route]) {
      return protobuf.decode(route, msg.body)
    } else {
      return JSON.parse(Protocol.strdecode(msg.body))
    }
  } catch (ex) {
    console.error(ex.stack)
  }

  return msg
}

pomelo.prototype.onKick = function (sefl, data) {
  this.emit('onKick')
}

pomelo.prototype.handshake = function (self, data) {

  data = JSON.parse(Protocol.strdecode(data))
  if (data.code === RES_OLD_CLIENT) {
    self.emit('error', 'client version not fullfill')
    return
  }

  if (data.code !== RES_OK) {
    self.emit('error', 'handshake fail')
    return
  }
  //self.handshakeInit(data);
  if (data.sys && data.sys.heartbeat) {
    self.heartbeatInterval = data.sys.heartbeat * 1000   // heartbeat interval
    self.heartbeatTimeout = self.heartbeatInterval * 2        // max heartbeat timeout
  } else {
    self.heartbeatInterval = 0
    self.heartbeatTimeout = 0
  }

  // self.initData(data);

  if (!data || !data.sys) {
    return
  }
  self.data = self.data || {}
  var dict = data.sys.dict
  var protos = data.sys.protos

  //Init compress dict
  if (!!dict) {
    self.data.dict = dict
    self.data.abbrs = {}

    for (var route in dict) {
      self.data.abbrs[dict[route]] = route
    }
  }

  //Init protobuf protos
  if (!!protos) {
    self.data.protos = {
      server: protos.server || {},
      client: protos.client || {}
    }
    if (!!protobuf) {
      protobuf.init({encoderProtos: protos.client, decoderProtos: protos.server})
    }
  }
  //
  if (typeof self.handshakeCallback === 'function') {

    self.handshakeCallback(data.user)
  }

  //

  var obj = Package.encode(Package.TYPE_HANDSHAKE_ACK)
  send(self, obj)

  if (self.initCallback) {
    self.initCallback(self, self.socket)
    self.initCallback = null
  }
}

pomelo.prototype.processPackage = function (msg) {
  var msg1 = new Buffer(msg.toString(), 'base64')

  this.handlers[msg.type](this, msg.body)
}

pomelo.prototype.initWebSocket = function (url, cb) {
  var self = this
  var onopen = function (event) {

    var obj = Package.encode(Package.TYPE_HANDSHAKE, Protocol.strencode(JSON.stringify(self.handshakeBuffer)))
    send(self, obj)
  }
  var onmessage = function (event) {

    self.processPackage(Package.decode(event.data), cb)
    // new package arrived, update the heartbeat timeout
    if (self.heartbeatTimeout) {
      self.nextHeartbeatTimeout = Date.now() + self.heartbeatTimeout
    }
  }
  var onerror = function (event) {

    self.emit('io-error', event)
  }
  var onclose = function (event) {

    self.emit('close', event)
  }
  this.socket = new WebSocket(url)
  this.socket.binaryType = 'arraybuffer'
  this.socket.onopen = onopen
  this.socket.onmessage = onmessage
  this.socket.onerror = onerror
  this.socket.onclose = onclose
}

pomelo.prototype.request = function (route, msg, cb) {
  msg = msg || {}
  route = route || msg.route
  if (!route) {
    return
  }

  this.reqId++
  var self = this
  sendMessage(self, self.reqId, route, msg)

  this.callbacks[this.reqId] = cb
  this.routeMap[this.reqId] = route
}

var sendMessage = function (self, reqId, route, msg) {
  var type = reqId ? Message.TYPE_REQUEST : Message.TYPE_NOTIFY

  //compress message by protobuf
  var protos = !!self.data.protos ? self.data.protos.client : {}
  if (!!protos[route]) {
    msg = protobuf.encode(route, msg)
  } else {
    msg = Protocol.strencode(JSON.stringify(msg))
  }

  var compressRoute = 0
  if (self.dict && self.dict[route]) {
    route = self.dict[route]
    compressRoute = 1
  }

  msg = Message.encode(reqId, type, compressRoute, route, msg)
  var packet = Package.encode(Package.TYPE_DATA, msg)
  send(self, packet)
}
pomelo.prototype.notify = function (route, msg) {
  msg = msg || {}
  sendMessage(this, 0, route, msg)
}

pomelo.prototype.disconnect = function () {
  if (this.socket) {
    if (this.socket.disconnect) this.socket.disconnect()
    if (this.socket.close) this.socket.close()
    this.socket = null
  }
  var self = this
  if (this.heartbeatId) {
    clearTimeout(self.heartbeatId)
    this.heartbeatId = null
  }
  if (this.heartbeatTimeoutId) {
    clearTimeout(self.heartbeatTimeoutId)
    this.heartbeatTimeoutId = null
  }
}

pomelo.prototype.heartbeat = function (self, data) {

  var obj = Package.encode(Package.TYPE_HEARTBEAT)
  if (self.heartbeatTimeoutId) {
    clearTimeout(self.heartbeatTimeoutId)
    self.heartbeatTimeoutId = null
  }

  if (self.heartbeatId) {
    // already in a heartbeat interval
    return
  }

  self.heartbeatId = setTimeout(function () {
    self.heartbeatId = null
    send(self, obj)

    self.nextHeartbeatTimeout = Date.now() + self.heartbeatTimeout
    self.heartbeatTimeoutId = setTimeout(self.heartbeatTimeoutCb, self.heartbeatTimeout)
  }, self.heartbeatInterval)
}

pomelo.prototype.heartbeatTimeoutCb = function () {
  var self = this
  var gap = self.nextHeartbeatTimeout - Date.now()
  if (gap > self.gapThreshold) {
    self.heartbeatTimeoutId = setTimeout(self.heartbeatTimeoutCb, gap)
  } else {
    self.emit('heartbeat timeout')
    self.disconnect()
  }
}

var send = function (self, packet) {
  if (!!self.socket) {
    self.socket.send(packet.buffer || packet, {binary: true, mask: true})
  }
}

var initPomleo = function (self) {
  self.handlers[Package.TYPE_HANDSHAKE] = self.handshake
  self.handlers[Package.TYPE_HEARTBEAT] = self.heartbeat
  self.handlers[Package.TYPE_DATA] = self.onData
  self.handlers[Package.TYPE_KICK] = self.onKick
}

module.exports = pomelo
  1. 问题描述

    • 以上代码, 在Node 6.* 版本中是无法连接到WebSocket服务端的, 但是在Node 8.*版本中就可以正常连接
    • 错误单词请忽略

关注 1 回答 0

Anguer 回答了问题 · 2018-05-16

解决javascript 里面关于 apply 绑定的不理解

在调用一个存在的函数时,你可以为其指定一个 this 对象。 this 指当前对象,也就是正在调用这个函数的对象。 使用 apply, 你可以只写一次这个方法然后在另一个对象中继承它,而不用在新对象中重复写该方法。

apply 与 call() 非常相似,不同之处在于提供参数的方式。apply 使用参数数组而不是一组参数列表(原文:a named set of parameters)。apply 可以使用数组字面量(array literal),如 fun.apply(this, ['eat', 'bananas']),或数组对象, 如 fun.apply(this, new Array('eat', 'bananas'))。

你也可以使用 arguments 对象作为 argsArray 参数。 arguments 是一个函数的局部变量。 它可以被用作被调用对象的所有未指定的参数。 这样,你在使用apply函数的时候就不需要知道被调用对象的所有参数。 你可以使用arguments来把所有的参数传递给被调用对象。 被调用对象接下来就负责处理这些参数。

关注 3 回答 2

Anguer 回答了问题 · 2017-12-20

解决Mongo,对于百十万以上的数据量,该如何提高查询性能(**索引并不是那么好使**)

该问题已解决,谢谢各位

关注 5 回答 5

Anguer 回答了问题 · 2017-12-20

解决i++和++i的问题?

这是执行顺序的问题,
i++在后为 先赋值,后运算
++i在前为 先运算,后赋值

所以看起来像这样

var i = 1
console.log(i) // i=1
i = i + 1 // = 2
console.log(i) // i=2
i = i + 1 // = 3

关注 5 回答 5

Anguer 提出了问题 · 2017-08-09

解决Mongo,对于百十万以上的数据量,该如何提高查询性能(**索引并不是那么好使**)

  1. 数据结构如下

    /* 6 */
    {
        "_id" : ObjectId("591e91ea0fde9f017a9d6e9d"),
        "app" : "啦啦啦啦",
        "date" : "2017-05-19",
        "uid" : 10002,
        "nickName" : "qwe",
        "count" : 2,
        "card" : 2
    }
    
    /* 7 */
    {
        "_id" : ObjectId("591ea6950fde9f017a9d7a13"),
        "app" : "呵呵呵",
        "date" : "2017-05-19",
        "uid" : 10003,
        "nickName" : "asd",
        "count" : 2,
        "card" : 2
    }
  2. 数据量已超数十万
  3. 尝试建立索引并没有得到预想的结果,反而更慢
  4. 求方案,在线等

关注 5 回答 5

Anguer 赞了回答 · 2017-08-09

解决js 循环**数据结构处理**问题, 遇到瓶颈,求方案(考虑性能)

var authPlayers = {};
        for(var i=0;i<users.length;i++){
            var use = users[i];
            var useIds = users[i].authPlayerIds;
            delete use.authPlayerIds;
            for(var j=0;j<useIds.length;j++){
                if( authPlayers[useIds[j]] == undefined ){
                    authPlayers[useIds[j]]=[];
                    authPlayers[useIds[j]].push(use);
                }else{
                    authPlayers[useIds[j]].push(use);
                }
                //console.log( authPlayers[useIds[j]]  )
            }
        }

关注 6 回答 4

Anguer 赞了回答 · 2017-08-09

解决js 循环**数据结构处理**问题, 遇到瓶颈,求方案(考虑性能)

var users = [
{id: 1, username: '123', authPlayerIds: [1001, 1002, 1003]},
{id: 2, username: 'qwe', authPlayerIds: [1003, 1004, 1005]},
{id: 3, username: 'fdf', authPlayerIds: [1002, 1007, 1088]},
{id: 4, username: 'dsa', authPlayerIds: [1001, 1022, 1033]}
];

 function test (users) {
 var obj = {};
 for (var i = 0; i < users.length; i++) {
     var item = users[i].authPlayerIds;
     var id = users[i].id;
     var username = users[i].username;

     for (var j = 0; j < item.length; j++) {
         if (obj[item[j]]){ // 已存在
             obj[item[j]].push({
                 id: id,
                 username: username
             })
         } else {
             obj[item[j]] = [{
                 id: id,
                 username: username
             }]
         }
     }
 }
 console.log(obj);
 }
 test(users);

这应该是最简单的方法了

关注 6 回答 4

Anguer 赞了回答 · 2017-08-09

解决js 循环**数据结构处理**问题, 遇到瓶颈,求方案(考虑性能)

var users = [
    {id: 1, username: '123', authPlayerIds: [1001, 1002, 1003]},
    {id: 2, username: 'qwe', authPlayerIds: [1003, 1004, 1005]},
    {id: 3, username: 'fdf', authPlayerIds: [1002, 1007, 1088]},
    {id: 4, username: 'dsa', authPlayerIds: [1001, 1022, 1033]},
]
var ret = {}
users.forEach(function(e){
    var ap = e.authPlayerIds
    ap.forEach(function(p){
        var t = {}
        if (ret[p]) {
            t.id = e.id || null
            t.username = e.username || null
        } else {
            ret[p] = []
            t.id = e.id || null
            t.username = e.username || null
        }
        ret[p].push(t)
    })
})

关注 6 回答 4

认证与成就

  • 获得 47 次点赞
  • 获得 18 枚徽章 获得 1 枚金徽章, 获得 4 枚银徽章, 获得 13 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

注册于 2017-05-19
个人主页被 1.2k 人浏览