ECMAScript6のアロー関数とPromiseまとめ - JavaScript

# はじめに

この記事ではアロー関数とpromiseについての、使い方のまとめです。とくにpromiseに関しては、非同期処理の鉄板、async.jsとの比較をしながらその実装方法を見ていきます。

そのまえに、ECMAScript6の基本構文はこちら。
[ECMAScript6の基本構文まとめ - JavaScript]
(http://qiita.com/takeharu/items/cbbe017bbdd120015ca0)

技術情報のみつぶやくアカウント作成しました。ECMAScript6などの最新情報も追っていきます。
Twitter: [@takeharumikami]
(https://twitter.com/takeharumikami)

RSSはこちら
Feedly: [Feedlyをフォロー]
(http://cloud.feedly.com/#subscription%2Ffeed%2Fhttp%3A%2F%2Fqiita.com%2Ftakeharu%2Ffeed)
RSS: http://qiita.com/takeharu/feed


# アロー関数

### アロー関数の記述の仕方

アロー関数では、従来の無名関数より簡潔に記述できます。

 - Before

```javascript
var show = function(text) {
  console.log(text);
};
```

 - After

1.「function」記法を「=>」記法へ

```javascript
// アロー関数
var show = (text) => {
  console.log(text);
};
```

2.引数が一つの時には()を省略可能

```javascript
var show = text => {
  console.log(text);
};
```

3.さらに一文の場合は、{}とreturnの省略も可能。

```javascript
var show = (text) => text + ' さようなら';

var text = show('こんにちは');
console.log(text); // こんにちは さようなら
```

### thisを束縛する

まずthisの挙動では、JavaScript初学者は必ずといっていいほど悩まされます。
今までだと、bindでthisを束縛したり、thisを別名の変数に退避する方法などがありました。一般的には後者の退避がよくつかわれます。_this, self, thatなどといった変数名にするのが通例となっています。
ECMAScript6からはアロー関数を用いることにより、thisを束縛し、予想通りの挙動を得ることができます。

thisの挙動についてはこちら
[JavaScriptの「this」は「4種類」？？]
(http://qiita.com/takeharu/items/9935ce476a17d6258e27)


- Before

```javascript
var counter = {
  count: 0,

  start: function() {
    // thisを別名で退避
    var self = this;

    setTimeout(function() {
      // ここでのthisはcounterではないため、退避した変数selfを使用する
      self.count++;
    }, 1000);
  }
};
```

- After

```javascript
var counter = {
  count: 0,

  start: function() {
    setTimeout(() => {
      this.count++
    }, 1000);
  }
};
```

# 非同期処理を処理する、Promise(async.jsとの比較)

こちらでは、非同期処理の鉄板、async.jsとの比較をしながらその実装方法を見ていきます。

async.jsの基本的な使い方はこちら
[JavaScriptのasync.jsでwaterfallとseries、parallelの違い]
(http://qiita.com/takeharu/items/84ffbee23b8edcbb2e21)

### Promise.resolveメソッドによる順次処理の実行(async.jsのwaterfall)

- asycn.waterfall

async.jsのwaterfallとの比較です。

```javascript
async.waterfall([
  function(callback) {
    console.log('1');
    setTimeout(function() {
      console.log('1 done');
      callback(null, 1);
    }, 100);
  },
  
  function(value, callback) { // value === 1
    console.log('2');
    setTimeout(function() {
      console.log('2 done');
      callback(null, 2);
    }, 50);
  },
  
  function(value, callback) { // value === 2
    console.log('3');
    setTimeout(function() {
      console.log('3 done');
      callback(null, 3);
    }, 10);
  }
], function(err, value) { // value === 3
  if (err) {
    return console.log(err);
  }
  console.log('all done.');
});

//出力結果
1
1 done
2
2 done
3
3 done
all done.
```

 - Promise.resolveメソッドによる順次処理

Promise.resolveメソッドでは、thenによるメソッドチェーンにより、直感的にわかりやすく、順次処理を実現できます。resolveの引数に後続の処理へと値を渡すことができます。

```javascript
Promise.resolve()
.then(function() {
  return new Promise(function(resolve, reject) {
    console.log('1');
    setTimeout(function() {
      console.log('1 done');
      resolve(1);
    }, 100);
  })
})
.then(function(value) { // value === 1
  return new Promise(function(resolve, reject) {
    console.log('2');
    setTimeout(function() {
      console.log('2 done');
      resolve(2);
    }, 50);
  });
})
.then(function(value) { // value === 2
  return new Promise(function(resolve, reject) {
    console.log('3');
    setTimeout(function() {
      console.log('3 done');
      resolve(3);
    }, 10);
  });
})
.then(function(value) { // value === 3
  console.log('all done');
})
.catch(function(err) {
  console.log(err);
})
;
  
//出力結果
1
1 done
2
2 done
3
3 done
all done.
```




### Promise.allメソッドによる非同期処理の複数同時実行(async.jsのparallel)

- async.parallel

async.jsのparallelとの比較です。

```javascript
async.parallel([
  function(callback) {
    console.log('1');
    setTimeout(function() {
      console.log('1 done');
      callback(null, 1);
    }, 100);
  },
  
  function(callback) {
    console.log('2');
    setTimeout(function() {
      console.log('2 done');
      callback(null, 2);
    }, 50);
  },
  
  function(callback) {
    console.log('3');
    setTimeout(function() {
      console.log('3 done');
      callback(null, 3);
    }, 10);
  }
], function(err, results) {
  if (err) { 
    return console.log(err);
  }
  console.log('all done');
  console.log(results);
});

//出力結果
1
2
3
3 done
2 done
1 done
all done
[1, 2, 3] 
```

- Promise.all

Promise.allメソッドでは、配列でPromiseオブジェクトを渡すことにより、それらの処理を非同期で並列に処理することが可能となります。

```javascript
Promise.all([
  new Promise(function(resolve, reject) {
    console.log('1');
    setTimeout(function() {
      console.log('1 done');
      resolve(1);
    }, 100);
  }),

  new Promise(function(resolve, reject) {
    console.log('2');
    setTimeout(function() {
      console.log('2 done');
      resolve(2);
    }, 50);
  }),

  new Promise(function(resolve, reject) {
    console.log('3');
    setTimeout(function() {
      console.log('3 done');
      resolve(3);
    }, 10);
  })
]).then(
  function(results) {
    console.log('all done');
    console.log(results);
  },

  function(err) {
    console.log(err);
  }
);

//出力結果
1
2
3
3 done
2 done
1 done
all done
[1, 2, 3] 
```

### Promise.raceメソッド

上記のようにPromise.allメソッドはすべての処理が完了されてから、後続の処理が実行されます。それに対してPromise.raceメソッドは、一つでも処理が完了されるとその時点で後続の処理を実行します。

```javascript
Promise.race([
  new Promise(function(resolve, reject) {
    console.log('1');
    setTimeout(function() {
      console.log('1 done');
      resolve(1);
    }, 100);
  }),

  new Promise(function(resolve, reject) {
    console.log('2');
    setTimeout(function() {
      console.log('2 done');
      resolve(2);
    }, 50);
  }),

  new Promise(function(resolve, reject) {
    console.log('3');
    setTimeout(function() {
      console.log('3 done');
      resolve(3);
    }, 10);
  })
]).then(
  function(results) {
    console.log('first done');
  },

  function(err) {
    console.log(err);
  }
);

//出力結果
1
2
3
3 done
first done
2 done
1 done
```

# 後編の記事

ECMAScript6の最後の記事ではクラスについてまとめます。


# アカウント

技術情報のみつぶやくアカウント作成しました。ECMAScript6などの最新情報も追っていきます。
Twitter: [@takeharumikami]
(https://twitter.com/takeharumikami)

RSSはこちら
Feedly: [Feedlyをフォロー]
(http://cloud.feedly.com/#subscription%2Ffeed%2Fhttp%3A%2F%2Fqiita.com%2Ftakeharu%2Ffeed)
RSS: http://qiita.com/takeharu/feed

# おすすめの記事

ECMAScript6の基本構文はこちら。
[もうはじめよう、ECMAScript6の基本構文まとめ - JavaScript]
(http://qiita.com/takeharu/items/cbbe017bbdd120015ca0)

JavaScriptでは関数型言語の一部の機能？実践的なJavaScriptの関数型とは。
[JavaScriptで関数型プログラミングの入門](http://qiita.com/takeharu/items/cf98d352ff574c5ac536)

良質なスタイルガイドを真似したいなら、GoogleやjQueryを参考に。
[Javascriptのスタイルガイドまとめ(おすすめ4選)](http://qiita.com/takeharu/items/dee0972e5f39bfd4d7c8)