问题
I want to make a CoffeeScript function that even if it is invoked multiple times, has its effects only run once.
Is one of these, or another way a good way to make a once-invokable function ? Is the extra do
an issue or actually better ?
once_maker_a = (f)->
done=false
->
f.call() unless done
done=true
once_maker_b = (f)->
do(done=false)->
->
f.call() unless done
done=true
oa = once_maker_a(-> console.log 'yay A')
ob = once_maker_b(-> console.log 'yay B')
oa()
yay A #runs the function passed to the once_maker
undefined #return value of console.log
oa()
undefined #look, does not reprint 'yay A'
ob()
yay B
undefined
ob()
undefined
I know about http://api.jquery.com/one/ and http://underscorejs.org/#once but in this case using those libraries is not an option.
回答1:
Is one of these a good way to make a once-invokable function?
As @UncleLaz stated in the comments, you're ignoring any arguments to the function. Also you don't memoize the return value of the function, and always just return true
. If you're really only caring about side effects, then that might not be a problem.
Is the extra do an issue or actually better?
In your case it's an issue. Check out the compiled javascript. Even if you corrected the indentation, it's not better since it's just unnecessarily introducing another scope.
A better, minimalistic way might be
once_maker = (f) ->
->
f?.apply this, arguments
f = null
(still not caring about the return value)
来源:https://stackoverflow.com/questions/23282582/how-do-i-execute-a-function-only-once-in-coffeescript