Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

199 页的中间件串联 #16

Open
cinyearchan opened this issue Apr 24, 2023 · 4 comments
Open

199 页的中间件串联 #16

cinyearchan opened this issue Apr 24, 2023 · 4 comments

Comments

@cinyearchan
Copy link

isEqual(a1, a2, (next) => functionMiddleware(nanMiddleware())(next))  // 这里得到的还是 false
@fengyangfifa
Copy link

fengyangfifa commented Jun 3, 2023

这是我按照作者的实现改良了一下

function type(data) {
  return Object.prototype.toString.call(data).slice(8, -1).toLowerCase()
}

function equalArray(value, other, enhancer) {
  if (value.length !== other.length) {
    return false;
  }

  for (let i = 0; i < value.length; i++) {
    if (!isEqual(value[i], other[i], enhancer)) {
      return false;
    }
  }

  return true;
}

function equalObject(value, other, enhancer) {
  const vKeys = Object.keys(value);
  const oKeys = Object.keys(other);

  if (vKeys.length !== oKeys.length) {
    return false;
  }

  for (let i = 0; i < vKeys.length; i++) {
    const v = value[vKeys[i]];
    const o = other[vKeys[i]];

    if (!isEqual(v, o, enhancer)) {
      return false;
    }
  }

  return true;
}

function isEqual(value, other, enhancer) {
  if (value === other) {
    return true;
  }

  const vType = type(value);
  const oType = type(other);

  if (vType !== oType) {
    return false;
  }

  if (vType === 'array') {
    return equalArray(value, other, enhancer);
  } else if (vType === 'object') {
    return equalObject(value, other, enhancer);
  }

  const next = () => {
    return value === other;
  }

  if (type(enhancer) === 'function') {
    return enhancer(next)(value, other);
  }

  return next();
}

function nanMiddleware() {
  return (next) => (value, other) => {
    if (Number.isNaN(value) && Number.isNaN(other)) {
      return true;
    }

    return next(value, other);
  }
}

function functionMiddleware() {
  return (next) => (value, other) => {
    if (type(value) === 'function' && type(other) === 'function') {
      return value.toString() === other.toString();
    }

    return next(value, other);
  }
}

function compose(...fns) {
  return fns.reduce((a, b) => (...args) => a(b(...args)));
}

const test3 = () => {
}
const test4 = () => {
}

const a1 = {a: NaN, b: test3};
const a2 = {a: NaN, b: test4};
console.log(isEqual(1, NaN, nanMiddleware()));
console.log(isEqual(a1, a2, compose(functionMiddleware(), nanMiddleware())));
console.log(isEqual(a1, a2, compose(nanMiddleware(), functionMiddleware())));
console.log(isEqual(a1, a2, (next) => functionMiddleware(nanMiddleware(next))));
console.log(isEqual([NaN], [NaN], nanMiddleware()));

@yanhaijing
Copy link
Member

感谢反馈

@yanhaijing
Copy link
Member

https://github.com/jsmini/isequal 这里有一个实战版的代码,可以看看

@daolanfler
Copy link

daolanfler commented Jun 5, 2023

主要在于非 compose 写法里面: next 应该作为「 nanMiddleware() 返回值」的参数吧。

// 感觉这个 next 也放错地方了 
console.log(isEqual(a1, a2, (next) => functionMiddleware(nanMiddleware(next)))); // true

// 我感觉应该是这样的,从上面 compose 的角度来说:
console.log(  isEqual(a1, a2, (next) => functionMiddleware(nanMiddleware()(next)))     ); // true 
//                                                                         ^?

// 书中是这样的
console.log(  isEqual(a1, a2, (next) => functionMiddleware(nanMiddleware())(next))   );  // false 
//                                                                          ^?

借用2楼的代码 @fengyangfifa ,在线 stackblitz link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants