LoginSignup
6
7

More than 5 years have passed since last update.

CoffeeScriptでPromiseを使ったときにハマった

Posted at

Atomのプラグインを書こうとして,CoffeeScriptを書いていたらPromiseの使用中にハマった.
もう既に誰かが踏んだ地雷な気がするし,Qiitaに記事があると思ったが,見つからなかったのでメモがてら残しておく.

やりたい事とコード

CoffeeScriptを使って,次のようなPromiseの使用をしたかった.

  1. thenの引数関数内で,メンバへのアクセスをする
  2. thenの引数関数内で,resolverejectを使う

then内で,非同期APIの結果の例外処理(JSON,DOMのパースなど)をして,さらに,成功時はメンバへアクセスして処理をするような感じで,例えば,次のようなコード(Promiseの必要がないコードだが,例という事で)

class Class
  n: 2

  func: ->
    new Promise(
      (resolve) -> resolve(10)
    ).then(
      (value) ->
        if value is 0
          reject("value is 0")
        else
          resolve(value * @n)
    ).then((value) -> console.log(value + " #result"))

が,これを動かすと,@nundefinedとなり(CoffeeScriptの仕様への自分の理解が正しければ当然),コンソールにはNaN #resultが表示されてしまう.

こういうcallbackを簡単にかくために,CoffeeScriptには=>という記法があるので,これを使うと次のように書ける.

class Class
  n: 2

  func: ->
    new Promise(
      (resolve) -> resolve(10)
    ).then(
      (value) =>
        if value is 0
          reject("value is 0")
        else
          resolve(value * @n)
    ).then((value) -> console.log(value + " #result"))

しかし,今度はUncaught (in promise) ReferenceError: resolve is not definedというエラーメッセージが表示される.
あまりちゃんと調べていないが,resolveは,this.resolveの意味であり,=>によってthisの動きが変わっているのだろう.

実験

どういうふうに書けば適切な動作をするのかを調べるべく,書き方を思いつく限り試して見た所,次のような結果になった.結局,new Promiseを使って記述するのが今回の場合は最善なのかな.

上手く動くコード

then((value) -> value)
then((value) => value * @n)
then((value) => new Promise((resolve, reject) => resolve(value * @n))

メンバにアクセス出来ずに変な動作をするコード

then((value) -> value * @n)

ReferenceErrorが起こるコード

(value) => resolve(value * @n)

最後に

他にもっと簡単な解決策があれば教えて頂けると嬉しいです.CoffeeScriptは触り始めたばっかりなので.

6
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7