Aigle vs Bluebird

## はじめに
[`Aigle`](https://github.com/suguru03/aigle)という`Promise`ライブラリを開発しています。このライブラリは速度・安全性・利便性を重視したライブラリで、ベンチマーク上だけでなく本番環境を考慮した最適化をしています。
今回は[`Bluebird`](https://github.com/petkaantonov/bluebird)と比較しつつ`Aigle`を紹介したいと思います。

## Benchmark
<div align="center">
<img width="524" alt="Screen Shot 2017-05-10 at 11.19.05 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/17390/428a62a6-8817-b644-74ca-bbc977e8691c.png">
<div style="text-align: center;">
benchmark doxbee
</div>
<img width="515" alt="Screen Shot 2017-05-10 at 11.21.30 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/17390/38830434-a0f8-d9a6-abd6-baf8b0716f01.png">
benchmark parallel
</div>

この上記の結果は[`Bluebird`のBenchmark](https://github.com/suguru03/bluebird/tree/aigle/benchmark)を実行した結果でです。`doxbee`は直列処理、`parallel`は並列処理になります。また`Bluebird`では、Dependenciesが異なる`Bluebird`のバージョンを持つときパフォーマンスが著しく低下します。`Aigle`では上記のパフォーマンス低下を防ぐ処理がされており、ベンチマーク上だけでなく本番環境でも同様のパフォーマンスが期待できます。詳しくは[こちらの記事](http://qiita.com/suguru03/items/17be3826eae65602ff88#%E3%81%AA%E3%81%9Caigle%E3%81%8C%E9%80%9F%E3%81%84%E3%81%AE%E3%81%8B)を読んでいただけたらと思います。

## Functions

`Aigle`は`Lodash`や`Async`と同じような関数を多数持っており、より高速でかつより可読性の高いコードを実現できます。いくつか例を紹介したいと思います。

### `Aigle.map` vs `Bluebird.map`
`Aigle.map`は`Bluebird`より[1.5倍ほど高速](https://github.com/suguru03/aigle/tree/master/benchmark#benchmark)で、かつ`Lodash`や`Async`と同様、Objectの引数を持つことができます。

```js
const object = {
  a: 1,
  b: 2,
  c: 3
};
Blubird.map(Object.keys(object), key => {
  const value = object[key];
  ...
});
Aigle.map(object, (value, key) => { ... });
```

またconcurrencyを使用したい場合、`Aigle.mapLimit`を使用することができます。これは`Async.mapLimit`と似た関数になります。

```js
const array = [1, 2, 3, 4, 5];

Bluebird.map(array, value => {
  console.log(value); // 1, 2, 5, 4, 3 オーダーが保証されていない
  return Bluebird.delay(10);
}, { concurrency: 2 });

Aigle.mapLimit(array, 2, value => {
  console.log(value); // 1, 2, 3, 4, 5　オーダーが保証されている
  return Aigle.delay(10);
});

// limitを定義しない場合、デフォルトが使用される。デフォルト値は8
Aigle.mapLimit(array, value => {
  console.log(value); // 1, 2, 3, 4, 5
  return Aigle.delay(10);
});
```

さらに`Aigle`では`Lodash`と同様のshorthandをサポートしています。

```js
const array = [{ name: 'barney' }, { name: 'fred' }];
Aigle.resolve(array)
  .map('name') // 非同期で呼ばれる
  .then(names => console.log(names)); // ['barney', 'fred']
```

### `Aigle.mapValues`

この関数は`Async.mapValues`や`Lodash.mapValues`と同様の関数です。`Aigle.map`に似た関数ですがObjectを返します。`Aigle`を使用することで、より可読性の高いコードを書くことができます。

```js

const object = { a: 1, b: 2, c: 3 };
const iterator = value => Promise.resolve(value * 2);

// Bluebird
const result = {};
Bluebird.each(Object.keys(object), key => {
  const value = object[key];
  return iterator(value)
    .then(val => {
      result[key] = val;
    });
}).then(() => console.log(result)); // { a: 2, b: 4, c: 6 }

// Aigle
Aigle.mapValues(object, iterator)
  .then(result => console.log(result)); // { a: 2, b: 4, c: 6 }
```

### `Aigle.times`

この関数は`Async.times`や`Lodash.times`ど同様の関数で、定義された回数iteratorを実行します。

```js
const n = 10;
const iterator = value => Promise.resolve(value * 2);

// Bluebird
const times = [];
for (let i = 0; i < n; i++) {
  times.push(i);
}
Bluebird.map(times, iterator)
  .then(result => console.log(result)); // [0, 2, 4, ..., 18]

// Aigle
Aigle.times(n, iterator)
  .then(result => console.log(result)); // [0, 2, 4, ..., 18]
```

## まとめ
`Aigle`はより高速・安全・メンテナンスがしやすいコードを実現できます。紹介した関数はほんの一部で`Async`や`Lodash`のような関数を多数持っており、`Async`や`Lodash`を使っている方でも簡単に使用することができると思います。ぜひ使ってみてください。

## リンク
- [Aigle](https://github.com/suguru03/aigle)
- [Bluebird](https://github.com/petkaantonov/bluebird)
- [英語版](https://hackernoon.com/aigle-vs-bluebird-5ed3becb4c4c)