简体   繁体   中英

Ensure all methods in a chained comparator in javascript are run before evaulating?

If I have the following snippet:

onClose={() => !isPostingConfig && onClickAway() && clearRoleErrors()}

I understand that if !isPostingConfig returns a falsy value, both onClickAway() and clearRoleError() will not be evaluated ie the methods will not run.

I know I can circumvent this by wrapping a method around this.

evaulate(){
  var a = !isPostingConfig
  var b = onClickAway()
  var c = clearRoleError()

  return a && b && c
}

But is there an easier to ensure all methods in a chained operator are run before evaluating the operators?

You can create an array of functions, and loop with Array.reduce() . Combine the result of each function with the previous one using the logical and operator ( && ). All the functions will execute, and the end result stay true if all return true , or false if at least one returns false .

const evaluate = (...args) => args.reduce((r, fn) => r && fn(), true)

and you can call it like this:

evaluate(() => !isPostingConfig, onClickAway, clearRoleError)

If you don't want to wrap all expressions with a function, you can add a typeof check:

const evaluate = (...args) => args.reduce((r, item) => r && (typeof item === 'function' ? item() : item), true)

and call it like this:

evaluate(!isPostingConfig, onClickAway, clearRoleError)

But is there an easier to ensure all methods in a chained operator are run before evaluating the operators?

You can use & instead of && assuming you're dealing with booleans (you are with !isPostingConfig , but I don't know the return values of your functions). & is the bitwise AND operator. It always evaluates both of its operands. Then it converts them to 32-bit integers and ANDs them together. false converts to 0 and true converts to 1 , so with boolean values, a & b & c will be 1 if they're all 1 or 0 if any of them is 0 .

Of course, the result will be a number, not a boolean, but you can convert it back:

onClose={() => Boolean(!isPostingConfig & onClickAway() & clearRoleErrors())}

You might give yourself andAll and orAll helper functions:

onClose={() => andAll(!isPostingConfig, onClickAway(), clearRoleErrors())}

The array methods every (= AND) and some (= OR) would work, but it's a bit cumbersome:

onClose={() => [!isPostingConfig, onClickAway(), clearRoleErrors()].every(Boolean)}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM