Skip to content

Instantly share code, notes, and snippets.

@xl1
Last active December 15, 2015 09:59
Show Gist options
  • Save xl1/5242591 to your computer and use it in GitHub Desktop.
Save xl1/5242591 to your computer and use it in GitHub Desktop.
非同期処理用の if
{ IF, ELSE } = Retention
get = (url) ->
r = new Retention()
xhr = new XMLHttpRequest()
xhr.open 'GET', url, true
xhr.onload = -> r.resolve xhr.responseText
xhr.onerror = -> r.reject xhr.statusText
xhr.send()
r
main = ->
data1 = get location.href
data2 = get 'http://example.com'
IF(data1.AND data2) ->
console.log '両方ともできた!'
IF(data1.OR data2) ->
console.log '片方はできた'
, ELSE ->
console.log '両方だめだった……'
main()
class Retention
@IF = IF = (ret) -> (success, fail) ->
if ret.resolved
success?()
else if ret.rejected
fail?()
else
success and ret.successCallbacks.push success
fail and ret.failCallbacks.push fail
ret
@UNLESS = UNLESS = (ret) -> (fail, success) ->
IF(ret) success, fail
@ELSE = ELSE = (x) -> x
@NOT = NOT = (ret) ->
r = new Retention()
IF(ret) -> r.reject(ret.result)
UNLESS(ret) -> r.resolve(ret.error)
r
@WHEN = WHEN = (ret) -> (callback) ->
IF(ret) callback, callback
result: null
error: null
resolved: false
rejected: false
constructor: ->
@successCallbacks = []
@failCallbacks = []
resolve: (result) ->
return if @resolved or @rejected
@resolved = true
@result = result
f() for f in @successCallbacks
return
reject: (error) ->
return if @resolved or @rejected
@rejected = true
@error = error
f() for f in @failCallbacks
return
AND: (ret) ->
r = new Retention()
IF(@) => IF(ret) -> r.resolve()
IF(ret) => IF(@) -> r.resolve()
UNLESS(@) -> r.reject()
UNLESS(ret) -> r.reject()
r
DAND: (ret) ->
# delayed and
# どちらかが reject されても、もう一つが resolve または reject されるまで待つ
r = new Retention()
IF(@) => IF(ret) -> r.resolve()
IF(ret) => IF(@) -> r.resolve()
UNLESS(@) => WHEN(ret) -> r.reject()
UNLESS(ret) => WHEN(@) -> r.reject()
r
OR: (ret) ->
# どちらかが resolve された時点で resolve
# 両方の result をとれるとは限らない
r = new Retention()
IF(@) -> r.resolve()
IF(ret) -> r.resolve()
UNLESS(@) => UNLESS(ret) -> r.reject()
UNLESS(ret) => UNLESS(@) -> r.reject()
r
DOR: (ret) ->
# delayed or
# どちらかが resolve されても、もう一つが resolve または reject されるまで待つ
# もし resolve した場合は両方の result が取れる
r = new Retention()
IF(@) => WHEN(ret) -> r.resolve()
IF(ret) => WHEN(@) -> r.resolve()
UNLESS(@) => UNLESS(ret) -> r.reject()
UNLESS(ret) => UNLESS(@) -> r.reject()
r
@xl1
Copy link
Author

xl1 commented Mar 26, 2013

# 一部省略
IF = (@_ret) -> (success) ->
  Retention._ret.successCallbacks.push success
ELSE = (fail) ->
  Retention._ret.failCallbacks.push fail

とすると ELSE の前のカンマ要らなくなるけど、気持ち悪い感じもする。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment