极客时间对于推广渠道会有返利优惠,比如山月在极客时间买了一门课,再把课程分享给好友购买,这时极客时间会向山月返利20元左右。
而我现在做了一个返利平台,你可以在上边通过山月的链接购买课程,此时极客时间会向我返利。为了共同学习,而你可以添加我的微信 (shanyue94),我将把极客时间给我的返利发一个红包全部返给你

# 如何实现类似 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) ? [] : {})
}

关于山月

我的项目:
我的微信:shanyue94,欢迎交流
Last Updated: 7/21/2019, 11:25:08 AM