阿里云双十一优惠活动,点击链接进行购买: 一年仅需89元即可以购买服务器~。我个人服务器为2核4G配置,也更加推荐购买 2核4G三年799元 配置的服务器。
你可以跟着我的笔记 当我有一台服务器时,我做了什么 来开始维护服务器并搭建应用,将引导你使用 docker 和 k8s 搭建一个自己的服务器开发集群。

# 如何实现类似 lodash.merge 的函数

# merge

merge 用来递归合并对象,相当于深层的 Object.assign。在 graphql 中会广泛用到 merge,如会经常使用 merge 来合并所有的 resolver,特别是 Mutation 如下示例

const rootResolver = {
  Query: {
  
  },
  Mutation: {
    login () {}
  }
}

const userResolver = {
  User: {
    createUser() {}
  }
}

const resolver = merge(rootResolver, userResolver)
// output
// {
//   Query: {},
//   Mutation: {
//     login () {},
//     createUser () {}
//   }
// }

另外,在前端进行 graphql 的查询时也经常需要使用到 merge。如在进行页面的性能优化时,为了避免一个 Query 耗时过久,页面渲染过于耗时,会拆成两个 Query,先渲染响应快的数据,在慢慢等待个别响应慢的数据。

以下是一个关于个人主页信息的 Query,但是其中有一个字段 dataNeedDelay3s 会在服务器耗时许久,会因为此字段加大了用户的等待时间,造成不友好的用户体验。此时会把此字段单独拆掉,优先渲染其它个人信息。

query PROFILE {
  me {
    id
    age
    name
    # 需要耗时3s的字段
    dataNeedDelay3s
  }
}

# 拆为以下两个茶轩
query PROFILE_ONE {
  me {
    id
    age
    name
  }
}

query PROFILE_TWO {
  me {
    dataNeedDelay3s
  }
}

此时就有 merge 的需求,查询完成后把两次查询结果给拼到一起。

关于拆 graphql 的 Query 的需求无处不在,如在服务端渲染时,需要把权限资源与非权限资源分开。

这里讲述下如何实现 merge

function isObject (value) {
  const type = typeof value
  return value !== null && (type === 'object' || type === 'function')
}

// { a: [{ b: 2 }] } { a: [{ c: 2 }]} -> { a: [{b:2}, {c:2}]}
// merge({o: {a: 3}}, {o: {b:4}}) => {o: {a:3, b:4}}
function merge (source, other) {
  if (!isObject(source) || !isObject(other)) {
    return other === undefined ? source : other
  }
  // 合并两个对象的 key,另外要区分数组的初始值为 []
  return Object.keys({
    ...source,
    ...other
  }).reduce((acc, key) => {
    // 递归合并 value
    acc[key] = merge(source[key], other[key])
    return acc
  }, Array.isArray(source) ? [] : {})
}
Last Updated: 2/10/2020, 12:50:49 PM