# Order

在函數式編程中，通常會將多個請求發送到相同的條件，因為即使鍵值相同，我們也必須將每個請求視為新服務，這意味著不必要的性能浪費。

![這是我們常見的請求模式](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LwD6MjHg3yMxWgKGDEI%2Fuploads%2FcRoFoFPkyIyQOck9pI6p%2Ffile.png?alt=media)

因此，當請求的條件相同，我們可以視為回傳結果相同，因此在第一次請求回傳之前所有相同鍵值的請求都會等待第一次回傳的結果。

![當理論上請求的結果相同時，只需要進行一次請求](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LwD6MjHg3yMxWgKGDEI%2Fuploads%2FFQEgwWWKQYRUgHhugTAe%2Ffile.png?alt=media)

## How To Use

Order是一個[Plugin](https://packhouse-doc.metalsheep.com/the-instance/plugin)，使用前必須先引用：

```javascript
let Order = require('packhouse/plugins/Order')
let Packhouse = require('packhouse')
let packhouse = new Packhouse()

packhouse.plugin(Order)
```

以下是Order是如何根據Key獲取快取結果：

```javascript
let group = {
    tools: {
        order: {
            install({ store, packhouse }) {
                store.order = packhouse.order()
            },
            handler(self, key) {
                self.store
                    .order
                    .use(key, self, (error, success) => {
                        setTimeout(() => {
                            success(Date.now())
                        }, 1000)
                    })
            }
        }
    }
}

packhouse.addGroup('demo', () => ({ data: group }))

Promise.all([
    packhouse.tool('demo/order').promise('myKey'),
    packhouse.tool('demo/order').promise('myKey')
]).then(([d1, d2]) => {
    console.log(d1 === d2) // true
})

Promise.all([
    packhouse.tool('demo/order').promise('myKey2'),
    packhouse.tool('demo/order').promise('myKey3')
]).then(([d1, d2]) => {
    console.log(d1 === d2) // flase
})

```

## Use

Use是Order主要的使用方法：

{% hint style="info" %}
Use不會長時間Cache結果，當結果回傳後就會清除該Key值的Cache。
{% endhint %}

```javascript
let order = packhouse.order()
order.use(key, { success, error }, handler)
```

除了使用Use方法外，可以個別的調適Order行為：

{% hint style="info" %}
我們不贅述內部細節，因為這不是Order建議的操作模式。
{% endhint %}

```javascript
let order = packhouse.order()
// 這是use呼叫的呼叫過程
order
    .getOrCreate(key)
    .buffer({
        success() { ... },
        error() { ... }
    })
    .finish(cache => cache.clear())
    .action((error, success) => {
        success( ... )
    })
```
