> For the complete documentation index, see [llms.txt](https://packhouse-doc.metalsheep.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://packhouse-doc.metalsheep.com/the-instance/invoke.md).

# Invoke

## Action

`action`最後的結果最由最後的參數(callback)呈現，第一個參數是錯誤，第二個參數為運算結果。

如果你的程式是同步的，那Action是完全同步的，但仍建議把全部的函式視為非同步。

{% hint style="info" %}
在某些狀況下第一個參數不會是`error`，詳情請參照[`noGood`](/the-instance/invoke.md#nogood)。
{% endhint %}

```javascript
packhouse.tool('math/sum').action(10, 20, (error, result) => {
    console.log(result) // 30
})
```

## Promise

如果使用Promise，則回傳Promise物件。

{% hint style="info" %}
在某些狀況下不會觸發`catch`，詳情請參照[`noGood`](/the-instance/invoke.md#nogood)。
{% endhint %}

```javascript
packhouse.tool('math/sum').promise(10, 20).then(result => {
    console.log(result) // 30
})
```

## Per Invoke

在執行Invoke前可以註冊一些行為。

### Pack

參數預處理，你可以在宣告之前先注入參數：

```javascript
packhouse
    .tool('math/sum')
    .pack(10)
    .action(10, (error, result) => {
        console.log(result) // 20
    })
```

#### In Include

在Install中引用`tool`時只要給予額外的參數也可以運行`pack`：

```javascript
const tool = {
    install({ include }) {
        include('sum').tool('sum', 10)
    }
}
```

在Include中引用`line`的後續參數也有`pack`的功能：

```javascript
const tool = {
    install({ include }) {
        include('math').line('math', 10)
    },
    handler(self) {
        self.line('math')()
            .action((error, result) => {
                console.log(result) // 10
            })
    }
}
```

### No Good

當錯誤處理時，由`noGood`接收。

{% hint style="info" %}
非監聽制，反覆宣告會覆蓋上一次的宣告。
{% endhint %}

#### Action

當宣告`noGood`後`action`的第一個參數會被移除。

```javascript
packhouse
    .tool('math/sum')
    .noGood(e => console.log(e))
    .action('1', '2', result => {
        // 這裡不工作
    })
```

#### Promise

當宣告`noGood`後`promise`不會被`reject`。

> 嚴格來說如果你使用的是Promise請使用`reject`而不是noGood

```javascript
packhouse
    .tool('math/sum')
    .noGood(e => console.log(e))
    .promise('1', '2')
    .then(() => {
        // 這裡會執行
    })
```

你可以運用第二個參數來強行宣告為`reject`。

```javascript
packhouse
    .tool('math/sum')
    .noGood(e => console.log(e), { reject: true })
    .promise('1', '2')
    .then(() => {
        // 這裡不會執行
    })
    .catch(() => {
        // 這裡會執行
    })
```

### Always

無論如何都會執行，事件發生在Action之後。

{% hint style="info" %}
非監聽制，反覆宣告會覆蓋上一次的宣告。
{% endhint %}

```javascript
packhouse
    .tool('math/sum')
    .always(({ result, success, context }) => {
        console.log(result) // 30
        console.log(success) // true
        console.log(context.id) // uuid, 每次執行都會配發一個新的id
        console.log(context.caller) // 如果該次呼叫是由另一個tool調用，可以得知是哪個id呼叫
    })
    .promise(10 , 20)
```

#### Promise

運行Promise時請使用`finally`而不是`alawys`。
