├── assets
└── logo.png
├── go.mod
├── .github
└── workflows
│ └── test.yaml
├── .gitignore
├── go.sum
├── LICENSE
├── examples
├── case0
│ └── demo.go
├── case4
│ └── demo.go
├── case8
│ └── demo.go
├── case6
│ └── demo.go
├── case12
│ └── demo.go
├── case11
│ └── demo.go
├── case5
│ └── demo.go
├── case1
│ └── demo.go
├── case2
│ └── demo.go
├── case10
│ └── demo.go
├── case9
│ └── demo.go
├── case7
│ └── demo.go
└── case3
│ └── demo.go
├── promise.go
├── promise_test.go
├── README_CN.md
└── README.md
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shengyanli1982/vowlink/HEAD/assets/logo.png
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/shengyanli1982/vowlink
2 |
3 | go 1.19
4 |
5 | require github.com/stretchr/testify v1.8.4
6 |
7 | require (
8 | github.com/davecgh/go-spew v1.1.1 // indirect
9 | github.com/pmezard/go-difflib v1.0.0 // indirect
10 | gopkg.in/yaml.v3 v3.0.1 // indirect
11 | )
12 |
--------------------------------------------------------------------------------
/.github/workflows/test.yaml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches: ["main"]
4 | pull_request:
5 | branches: ["main"]
6 | name: Test
7 | jobs:
8 | test:
9 | strategy:
10 | matrix:
11 | go-version: [1.18.x, 1.19.x, 1.20.x, 1.21.x, 1.22.x]
12 | os: [ubuntu-latest, macos-latest, windows-latest]
13 | runs-on: ${{ matrix.os }}
14 | steps:
15 | - uses: actions/setup-go@v4
16 | with:
17 | go-version: "${{ matrix.go-version }}"
18 | - uses: actions/checkout@v3
19 | - name: Test
20 | run: go test -v ./...
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # If you prefer the allow list template instead of the deny list, see community template:
2 | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
3 | #
4 | # Binaries for programs and plugins
5 | *.exe
6 | *.exe~
7 | *.dll
8 | *.so
9 | *.dylib
10 |
11 | # Test binary, built with `go test -c`
12 | *.test
13 |
14 | # Output of the go coverage tool, specifically when used with LiteIDE
15 | *.out
16 |
17 | # Dependency directories (remove the comment below to include it)
18 | # vendor/
19 |
20 | # Go workspace file
21 | # go.work
22 |
23 | .idea
24 | .vscode
25 | .DS_Store
26 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
6 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
7 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
8 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
9 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
10 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Kuma (路口IT大叔)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/examples/case0/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | vl "github.com/shengyanli1982/vowlink"
7 | )
8 |
9 | func main() {
10 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
11 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
12 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
13 | // 这个 promise 直接解析为 "hello world"
14 | // This promise is directly resolved to "hello world"
15 | resolve("hello world", nil)
16 | }).Then(func(value interface{}) (interface{}, error) {
17 | // 在第一个 Then 方法中,我们将解析的值加上 " vowlink"
18 | // In the first Then method, we append " vowlink" to the resolved value
19 | return value.(string) + " vowlink", nil
20 | }, nil).Then(func(value interface{}) (interface{}, error) {
21 | // 在第二个 Then 方法中,我们将解析的值加上 " !!"
22 | // In the second Then method, we append " !!" to the resolved value
23 | return value.(string) + " !!", nil
24 | }, nil)
25 |
26 | // 从 promise 中获取值并打印
27 | // Get the value from the promise and print it
28 | fmt.Println(result.GetValue())
29 | }
30 |
--------------------------------------------------------------------------------
/examples/case4/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | vl "github.com/shengyanli1982/vowlink"
7 | )
8 |
9 | func main() {
10 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
11 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
12 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
13 | // 这个 promise 直接解析为 "hello world"
14 | // This promise is directly resolved to "hello world"
15 | resolve("hello world", nil)
16 | }).Then(func(value interface{}) (interface{}, error) {
17 | // 在 Then 方法中,我们创建一个新的 promise,将解析的值加上 " vowlink(NewPromise)"
18 | // In the Then method, we create a new promise, appending " vowlink(NewPromise)" to the resolved value
19 | return vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
20 | resolve(value.(string)+" vowlink(NewPromise)", nil)
21 | }), nil
22 | }, nil).Then(func(value interface{}) (interface{}, error) {
23 | // 在这个 Then 方法中,我们获取前一个 promise 的值,并加上 " !!"
24 | // In this Then method, we get the value from the previous promise and append " !!"
25 | return value.(*vl.Promise).GetValue().(string) + " !!", nil
26 | }, nil)
27 |
28 | // 从 promise 中获取值并打印
29 | // Get the value from the promise and print it
30 | fmt.Println(result.GetValue())
31 | }
32 |
--------------------------------------------------------------------------------
/examples/case8/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 |
7 | vl "github.com/shengyanli1982/vowlink"
8 | )
9 |
10 | func main() {
11 | // 创建 3 个 promise
12 | // Create 3 promises
13 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
14 | // 第一个 promise 直接解析为 "Promise 1"
15 | // The first promise is directly resolved to "Promise 1"
16 | resolve("Promise 1", nil)
17 | })
18 |
19 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
20 | // 第二个 promise 被拒绝,原因是 "Promise 2 rejected"
21 | // The second promise is rejected with the reason "Promise 2 rejected"
22 | reject(nil, errors.New("Promise 2 rejected"))
23 | })
24 |
25 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
26 | // 第三个 promise 直接解析为 "Promise 3"
27 | // The third promise is directly resolved to "Promise 3"
28 | resolve("Promise 3", nil)
29 | })
30 |
31 | // AllSettled() 将等待所有的 promise 被解析或拒绝,并返回一个带有值的 promise
32 | // AllSettled() will wait for all promises to be resolved or rejected, and return a promise with the value
33 | result := vl.AllSettled(p1, p2, p3)
34 |
35 | // 从 promise 中获取所有的结果
36 | // Get all the results from the promise
37 | for i, r := range result.GetValue().([]interface{}) {
38 | // 如果结果是一个错误,打印错误信息
39 | // If the result is an error, print the error message
40 | if v, ok := r.(error); ok {
41 | fmt.Println("!!", i, v.Error())
42 | } else {
43 | // 否则,打印结果值
44 | // Otherwise, print the result value
45 | fmt.Println(">>", i, r.(string))
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/case6/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | vl "github.com/shengyanli1982/vowlink"
7 | )
8 |
9 | func main() {
10 | // 创建 3 个 promise
11 | // Create 3 promises
12 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
13 | // 第一个 promise 直接解析为 "Promise"
14 | // The first promise is directly resolved to "Promise"
15 | resolve("Promise", nil)
16 | }).Then(func(value interface{}) (interface{}, error) {
17 | // 在 Then 方法中,将解析的值加上 " 1"
18 | // In the Then method, append " 1" to the resolved value
19 | return value.(string) + " 1", nil
20 | }, nil)
21 |
22 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
23 | // 第二个 promise 直接解析为 "Promise"
24 | // The second promise is directly resolved to "Promise"
25 | resolve("Promise", nil)
26 | }).Then(func(value interface{}) (interface{}, error) {
27 | // 在 Then 方法中,将解析的值加上 " 2"
28 | // In the Then method, append " 2" to the resolved value
29 | return value.(string) + " 2", nil
30 | }, nil)
31 |
32 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
33 | // 第三个 promise 直接解析为 "Promise"
34 | // The third promise is directly resolved to "Promise"
35 | resolve("Promise", nil)
36 | }).Then(func(value interface{}) (interface{}, error) {
37 | // 在 Then 方法中,将解析的值加上 " 3"
38 | // In the Then method, append " 3" to the resolved value
39 | return value.(string) + " 3", nil
40 | }, nil)
41 |
42 | // Race() 将等待第一个 promise 被解析,并返回一个带有值的 promise
43 | // Race() will wait for the first promise to be resolved, and return a promise with the value
44 | result := vl.Race(p1, p2, p3)
45 |
46 | // 从 promise 中获取值并打印
47 | // Get the value from the promise and print it
48 | fmt.Println(">>", result.GetValue().(string))
49 | }
50 |
--------------------------------------------------------------------------------
/examples/case12/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 |
7 | vl "github.com/shengyanli1982/vowlink"
8 | )
9 |
10 | func main() {
11 |
12 | // 创建一个新的 Promise
13 | // Create a new Promise
14 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
15 | // 这个 Promise 将继续执行,并将错误 "Something went wrong" 作为值传递给下一个 Promise
16 | // This Promise will continue to execute and pass the error "Something went wrong" as a value to the next Promise
17 | reject("Something went wrong", nil)
18 |
19 | }).Then(func(data interface{}) (interface{}, error) {
20 | // 当 Promise 被解决时,会执行这个 Then 函数
21 | // This Then function will be executed when the Promise is resolved
22 | fmt.Println("> then 1")
23 |
24 | // 返回解决的值,将会被下一个 Then 函数接收
25 | // Return the resolved value, which will be received by the next Then function
26 | return data, nil
27 |
28 | }, func(error) (interface{}, error) {
29 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
30 | // This Catch function will be executed when the Promise is rejected
31 | fmt.Println("> catch 1")
32 |
33 | // 返回一个新的错误 "Handled error"
34 | // Return a new error "Handled error"
35 | return nil, errors.New("Handled error")
36 |
37 | }).Catch(func(reason error) (interface{}, error) {
38 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
39 | // This Catch function will be executed when the Promise is rejected
40 | fmt.Println("> catch 2")
41 |
42 | // 返回一个字符串,表示恢复的值
43 | // Return a string representing the recovered value
44 | return fmt.Sprintf("Recovered value: %v", reason.Error()), nil
45 |
46 | })
47 |
48 | // 输出 Promise 的拒绝原因
49 | // Print the rejection reason of the Promise
50 | fmt.Println("reason: ", result.GetReason())
51 |
52 | // 输出 Promise 的解决值
53 | // Print the resolution value of the Promise
54 | fmt.Println("value: ", result.GetValue())
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/examples/case11/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 |
7 | vl "github.com/shengyanli1982/vowlink"
8 | )
9 |
10 | // 定义 main 函数
11 | // Define the main function
12 | func main() {
13 |
14 | // 创建一个新的 Promise
15 | // Create a new Promise
16 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
17 | // 这个 Promise 将继续执行,并将错误 "Something went wrong" 作为值传递给下一个 Promise
18 | // This Promise will continue to execute and pass the error "Something went wrong" as a value to the next Promise
19 | resolve(errors.New("Something went wrong"), nil)
20 |
21 | }).Then(func(data interface{}) (interface{}, error) {
22 | // 当 Promise 被解决时,会执行这个 Then 函数
23 | // This Then function will be executed when the Promise is resolved
24 | fmt.Println("> then 1")
25 |
26 | // 返回错误的字符串表示形式
27 | // Return the string representation of the error
28 | return data.(error).Error(), nil
29 |
30 | }, func(error) (interface{}, error) {
31 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
32 | // This Catch function will be executed when the Promise is rejected
33 | fmt.Println("> catch 1")
34 |
35 | // 返回一个新的错误 "Handled error"
36 | // Return a new error "Handled error"
37 | return nil, errors.New("Handled error")
38 |
39 | }).Catch(func(reason error) (interface{}, error) {
40 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
41 | // This Catch function will be executed when the Promise is rejected
42 | fmt.Println("> catch 2")
43 |
44 | // 返回一个字符串,表示恢复的值
45 | // Return a string representing the recovered value
46 | return fmt.Sprintf("Recovered value: %v", reason.Error()), nil
47 |
48 | })
49 |
50 | // 输出 Promise 的拒绝原因
51 | // Print the rejection reason of the Promise
52 | fmt.Println("reason: ", result.GetReason())
53 |
54 | // 输出 Promise 的解决值
55 | // Print the resolution value of the Promise
56 | fmt.Println("value: ", result.GetValue())
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/examples/case5/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | vl "github.com/shengyanli1982/vowlink"
7 | )
8 |
9 | func main() {
10 | // 创建 3 个 promise
11 | // Create 3 promises
12 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
13 | // 第一个 promise 直接解析为 "Promise"
14 | // The first promise is directly resolved to "Promise"
15 | resolve("Promise", nil)
16 | }).Then(func(value interface{}) (interface{}, error) {
17 | // 在 Then 方法中,将解析的值加上 " 1"
18 | // In the Then method, append " 1" to the resolved value
19 | return value.(string) + " 1", nil
20 | }, nil)
21 |
22 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
23 | // 第二个 promise 直接解析为 "Promise"
24 | // The second promise is directly resolved to "Promise"
25 | resolve("Promise", nil)
26 | }).Then(func(value interface{}) (interface{}, error) {
27 | // 在 Then 方法中,将解析的值加上 " 2"
28 | // In the Then method, append " 2" to the resolved value
29 | return value.(string) + " 2", nil
30 | }, nil)
31 |
32 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
33 | // 第三个 promise 直接解析为 "Promise"
34 | // The third promise is directly resolved to "Promise"
35 | resolve("Promise", nil)
36 | }).Then(func(value interface{}) (interface{}, error) {
37 | // 在 Then 方法中,将解析的值加上 " 3"
38 | // In the Then method, append " 3" to the resolved value
39 | return value.(string) + " 3", nil
40 | }, nil)
41 |
42 | // All() 将等待所有的 promise 被解析,并返回一个带有所有值的 promise
43 | // All() will wait for all promises to be resolved, and return a promise with all the values
44 | result := vl.All(p1, p2, p3)
45 |
46 | // 从 promise 中获取所有的值并打印
47 | // Get all the values from the promise and print them
48 | for i, str := range result.GetValue().([]interface{}) {
49 | fmt.Println(">>", i, str.(string))
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/examples/case1/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | vl "github.com/shengyanli1982/vowlink"
7 | )
8 |
9 | func main() {
10 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
11 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
12 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
13 | // 这个 promise 直接解析为 "hello world"
14 | // This promise is directly resolved to "hello world"
15 | resolve("hello world", nil)
16 | }).Then(func(value interface{}) (interface{}, error) {
17 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
18 | // In the Then method, we append " vowlink !!" to the resolved value
19 | return value.(string) + " vowlink !!", nil
20 | }, func(err error) (interface{}, error) {
21 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
22 | // If the promise is rejected, we return a new error message "rejected."
23 | return nil, fmt.Errorf("rejected.")
24 | })
25 |
26 | // 从 promise 中获取值并打印
27 | // Get the value from the promise and print it
28 | fmt.Println("Resolve:", result.GetValue())
29 |
30 | // 这是一个被拒绝的 promise
31 | // This is a rejected promise
32 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
33 | // 这个 promise 被拒绝,原因是 "error"
34 | // This promise is rejected with the reason "error"
35 | reject(nil, fmt.Errorf("error"))
36 | }).Then(func(value interface{}) (interface{}, error) {
37 | // 如果 promise 被解析,我们将解析的值加上 " vowlink"
38 | // If the promise is resolved, we append " vowlink" to the resolved value
39 | return value.(string) + " vowlink", nil
40 | }, func(err error) (interface{}, error) {
41 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
42 | // If the promise is rejected, we return a new error message "rejected."
43 | return nil, fmt.Errorf("rejected.")
44 | })
45 |
46 | // 从 promise 中获取拒绝的原因并打印
47 | // Get the reason for the rejection from the promise and print it
48 | fmt.Println("Rejected:", result.GetReason().Error())
49 | }
50 |
--------------------------------------------------------------------------------
/examples/case2/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | vl "github.com/shengyanli1982/vowlink"
7 | )
8 |
9 | func main() {
10 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
11 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
12 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
13 | // 这个 promise 直接解析为 "hello world"
14 | // This promise is directly resolved to "hello world"
15 | resolve("hello world", nil)
16 | }).Then(func(value interface{}) (interface{}, error) {
17 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
18 | // In the Then method, we append " vowlink !!" to the resolved value
19 | return value.(string) + " vowlink !!", nil
20 | }, nil).Catch(func(err error) (interface{}, error) {
21 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
22 | // If the promise is rejected, we return a new error message "rejected."
23 | return nil, fmt.Errorf("rejected.")
24 | })
25 |
26 | // 从 promise 中获取值并打印
27 | // Get the value from the promise and print it
28 | fmt.Println("Resolve:", result.GetValue())
29 |
30 | // 这是一个被拒绝的 promise
31 | // This is a rejected promise
32 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
33 | // 这个 promise 被拒绝,原因是 "error"
34 | // This promise is rejected with the reason "error"
35 | reject(nil, fmt.Errorf("error"))
36 | }).Then(func(value interface{}) (interface{}, error) {
37 | // 如果 promise 被解析,我们将解析的值加上 " vowlink !!"
38 | // If the promise is resolved, we append " vowlink !!" to the resolved value
39 | return value.(string) + " vowlink !!", nil
40 | }, nil).Catch(func(err error) (interface{}, error) {
41 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
42 | // If the promise is rejected, we return a new error message "rejected."
43 | return nil, fmt.Errorf("rejected.")
44 | })
45 |
46 | // 从 promise 中获取拒绝的原因并打印
47 | // Get the reason for the rejection from the promise and print it
48 | fmt.Println("Rejected:", result.GetReason().Error())
49 | }
50 |
--------------------------------------------------------------------------------
/examples/case10/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 |
7 | vl "github.com/shengyanli1982/vowlink"
8 | )
9 |
10 | func main() {
11 |
12 | // 创建一个新的 Promise
13 | // Create a new Promise
14 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
15 | // 这个 Promise 会立即被拒绝,原因是 "rejected.100"
16 | // This Promise will be immediately rejected with the reason "rejected.100"
17 | reject(nil, fmt.Errorf("rejected.100"))
18 |
19 | }).Catch(func(err error) (interface{}, error) {
20 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
21 | // This Catch function will be executed when the Promise is rejected
22 | fmt.Println("> catch 1")
23 |
24 | // 返回一个新的错误,将会被下一个 Catch 函数接收
25 | // Return a new error, which will be received by the next Catch function
26 | return nil, err
27 |
28 | }).Catch(func(err error) (interface{}, error) {
29 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
30 | // This Catch function will be executed when the previous Catch function returns an error
31 | fmt.Println("> catch 2")
32 |
33 | // 返回一个新的值,将会被下一个 Then 函数接收
34 | // Return a new value, which will be received by the next Then function
35 | return "[error handled]", nil
36 |
37 | }).Catch(func(err error) (interface{}, error) {
38 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
39 | // This Catch function will be executed when the previous Catch function returns an error
40 | fmt.Println("> catch 3")
41 |
42 | // 返回一个新的错误,将会被下一个 Catch 函数接收
43 | // Return a new error, which will be received by the next Catch function
44 | return nil, errors.New("rejected.200")
45 |
46 | }).Then(func(value interface{}) (interface{}, error) {
47 | // 当 Promise 被解决时,会执行这个 Then 函数
48 | // This Then function will be executed when the Promise is resolved
49 | fmt.Println("> then 1")
50 |
51 | // 返回一个新的值,将会被下一个 Then 函数接收
52 | // Return a new value, which will be received by the next Then function
53 | return fmt.Sprintf("Should be here. recover value: %v", value), nil
54 |
55 | }, func(err error) (interface{}, error) {
56 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
57 | // This Catch function will be executed when the Promise is rejected
58 | fmt.Println("> catch 4")
59 |
60 | // 返回一个新的错误,将会被下一个 Catch 函数接收
61 | // Return a new error, which will be received by the next Catch function
62 | return nil, errors.New("Never be here!!")
63 |
64 | })
65 |
66 | // 输出 Promise 的拒绝原因,这里一定是 "nil"
67 | // Print the rejection reason of the Promise, it must be "nil" here
68 | fmt.Println("reason: ", result.GetReason())
69 |
70 | // 输出 Promise 的解决值,这里一定是 "Should be here."
71 | // Print the resolution value of the Promise, it must be "Should be here." here
72 | fmt.Println("value: ", result.GetValue())
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/examples/case9/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 |
7 | vl "github.com/shengyanli1982/vowlink"
8 | )
9 |
10 | func main() {
11 |
12 | // 创建一个新的 Promise
13 | // Create a new Promise
14 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
15 | // 这个 Promise 会立即被拒绝,原因是 "rejected.100"
16 | // This Promise will be immediately rejected with the reason "rejected.100"
17 | reject(nil, fmt.Errorf("rejected.100"))
18 |
19 | }).Catch(func(err error) (interface{}, error) {
20 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
21 | // This Catch function will be executed when the Promise is rejected
22 | fmt.Println("> catch 1")
23 |
24 | // 返回一个新的错误,将会被下一个 Catch 函数接收
25 | // Return a new error, which will be received by the next Catch function
26 | return nil, err
27 |
28 | }).Catch(func(err error) (interface{}, error) {
29 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
30 | // This Catch function will be executed when the previous Catch function returns an error
31 | fmt.Println("> catch 2")
32 |
33 | // 返回一个新的错误,将会被下一个 Catch 函数接收
34 | // Return a new error, which will be received by the next Catch function
35 | return nil, errors.New("rejected.200")
36 |
37 | }).Catch(func(err error) (interface{}, error) {
38 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
39 | // This Catch function will be executed when the previous Catch function returns an error
40 | fmt.Println("> catch 3")
41 |
42 | // 返回一个新的错误,将会被下一个 Catch 函数接收
43 | // Return a new error, which will be received by the next Catch function
44 | return nil, errors.New("rejected.300")
45 |
46 | }).Then(func(value interface{}) (interface{}, error) {
47 | // 当 Promise 被解决时,会执行这个 Then 函数
48 | // This Then function will be executed when the Promise is resolved
49 | fmt.Println("> then 1")
50 |
51 | // 返回一个新的值,将会被下一个 Then 函数接收
52 | // Return a new value, which will be received by the next Then function
53 | return fmt.Sprintf("Never be here!! recover value: %v", value), nil
54 |
55 | }, func(err error) (interface{}, error) {
56 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
57 | // This Catch function will be executed when the Promise is rejected
58 | fmt.Println("> catch 4")
59 |
60 | // 返回一个新的错误,将会被下一个 Catch 函数接收
61 | // Return a new error, which will be received by the next Catch function
62 | return nil, errors.New("Should be here.")
63 | })
64 |
65 | // 打印 Promise 被拒绝的原因
66 | // Print the reason the Promise was rejected
67 | fmt.Println("reason: ", result.GetReason())
68 |
69 | // 打印 Promise 的值,但是在这个例子中,Promise 会被拒绝,所以值会是 nil
70 | // Print the value of the Promise, but in this case, the Promise will be rejected, so the value will be nil
71 | fmt.Println("value: ", result.GetValue())
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/examples/case7/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 |
7 | vl "github.com/shengyanli1982/vowlink"
8 | )
9 |
10 | func main() {
11 | // 创建 3 个 promise
12 | // Create 3 promises
13 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
14 | // 第一个 promise 直接解析为 "Promise"
15 | // The first promise is directly resolved to "Promise"
16 | resolve("Promise", nil)
17 | }).Then(func(value interface{}) (interface{}, error) {
18 | // 在 Then 方法中,将解析的值加上 " 1"
19 | // In the Then method, append " 1" to the resolved value
20 | return value.(string) + " 1", nil
21 | }, nil)
22 |
23 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
24 | // 第二个 promise 直接解析为 "Promise"
25 | // The second promise is directly resolved to "Promise"
26 | resolve("Promise", nil)
27 | }).Then(func(value interface{}) (interface{}, error) {
28 | // 在 Then 方法中,将解析的值加上 " 2"
29 | // In the Then method, append " 2" to the resolved value
30 | return value.(string) + " 2", nil
31 | }, nil)
32 |
33 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
34 | // 第三个 promise 直接解析为 "Promise"
35 | // The third promise is directly resolved to "Promise"
36 | resolve("Promise", nil)
37 | }).Then(func(value interface{}) (interface{}, error) {
38 | // 在 Then 方法中,将解析的值加上 " 3"
39 | // In the Then method, append " 3" to the resolved value
40 | return value.(string) + " 3", nil
41 | }, nil)
42 |
43 | // Any() 将等待第一个 promise 被解析,并返回一个带有值的 promise
44 | // Any() will wait for the first promise to be resolved, and return a promise with the value
45 | result := vl.Any(p1, p2, p3)
46 |
47 | // 从 promise 中获取值并打印
48 | // Get the value from the promise and print it
49 | fmt.Println(">>", result.GetValue().(string))
50 |
51 | // 创建 3 个 promise
52 | // Create 3 promises
53 | p1 = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
54 | // 第一个 promise 被拒绝,原因是 "Promise 1 rejected"
55 | // The first promise is rejected with the reason "Promise 1 rejected"
56 | reject(nil, errors.New("Promise 1 rejected"))
57 | })
58 |
59 | p2 = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
60 | // 第二个 promise 被拒绝,原因是 "Promise 2 rejected"
61 | // The second promise is rejected with the reason "Promise 2 rejected"
62 | reject(nil, errors.New("Promise 2 rejected"))
63 | })
64 |
65 | p3 = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
66 | // 第三个 promise 被拒绝,原因是 "Promise 3 rejected"
67 | // The third promise is rejected with the reason "Promise 3 rejected"
68 | reject(nil, errors.New("Promise 3 rejected"))
69 | })
70 |
71 | // Any() 将等待所有的 promise 被拒绝,并返回一个带有原因 `AggregateError` 的 promise
72 | // Any() will wait for all promises to be rejected, and return a promise with the reason `AggregateError`
73 | result = vl.Any(p1, p2, p3)
74 |
75 | // 从 promise 中获取原因并打印
76 | // Get the reason from the promise and print it
77 | fmt.Println("!!", result.GetReason().Error())
78 | }
79 |
--------------------------------------------------------------------------------
/promise.go:
--------------------------------------------------------------------------------
1 | package vowlink
2 |
3 | import "strings"
4 |
5 | // PromiseState represents the state of a Promise
6 | // PromiseState 表示 Promise 的状态
7 | type PromiseState uint8
8 |
9 | // Default handlers for Promise operations
10 | // Promise 操作的默认处理函数
11 | var (
12 | defaultSuccessHandler = func(value interface{}) (interface{}, error) { return value, nil }
13 | defaultErrorHandler = func(err error) (interface{}, error) { return nil, err }
14 | defaultCleanupHandler = func() error { return nil }
15 | )
16 |
17 | // AggregateError represents a collection of errors
18 | // AggregateError 表示错误集合
19 | type AggregateError struct {
20 | Errors []error
21 | }
22 |
23 | func (ae *AggregateError) Error() string {
24 | if len(ae.Errors) == 0 {
25 | return "All promises were rejected"
26 | }
27 |
28 | errStrings := make([]string, 0, len(ae.Errors))
29 | for _, err := range ae.Errors {
30 | if err != nil {
31 | errStrings = append(errStrings, err.Error())
32 | }
33 | }
34 | return "All promises were rejected: " + strings.Join(errStrings, ", ")
35 | }
36 |
37 | func NewAggregateError(capacity int) *AggregateError {
38 | return &AggregateError{
39 | Errors: make([]error, 0, capacity),
40 | }
41 | }
42 |
43 | // Promise states constants
44 | // Promise 状态常量
45 | const (
46 | Pending PromiseState = iota // Promise is pending / Promise 正在等待
47 | Fulfilled // Promise is fulfilled / Promise 已成功完成
48 | Rejected // Promise is rejected / Promise 已拒绝
49 | )
50 |
51 | // Promise represents an asynchronous operation
52 | // Promise 表示一个异步操作
53 | type Promise struct {
54 | state PromiseState
55 | value interface{}
56 | reason error
57 | }
58 |
59 | func (p *Promise) change(state PromiseState, value interface{}, reason error) {
60 | if p.state == Pending {
61 | p.state = state
62 | p.value = value
63 | p.reason = reason
64 | }
65 | }
66 |
67 | func (p *Promise) resolve(value interface{}, reason error) {
68 | p.change(Fulfilled, value, reason)
69 | }
70 |
71 | func (p *Promise) reject(value interface{}, reason error) {
72 | p.change(Rejected, value, reason)
73 | }
74 |
75 | // NewPromise creates a new Promise with the given handler
76 | // NewPromise 使用给定的处理函数创建新的 Promise
77 | func NewPromise(promiseHandler func(resolve func(interface{}, error), reject func(interface{}, error))) *Promise {
78 | if promiseHandler == nil {
79 | return nil
80 | }
81 |
82 | p := &Promise{state: Pending}
83 |
84 | promiseHandler(p.resolve, p.reject)
85 |
86 | return p
87 | }
88 |
89 | // Then registers callbacks to be called when the Promise is settled
90 | // Then 注册 Promise 完成时要调用的回调函数
91 | func (p *Promise) Then(successHandler func(interface{}) (interface{}, error), errorHandler func(error) (interface{}, error)) *Promise {
92 | if successHandler == nil {
93 | successHandler = defaultSuccessHandler
94 | }
95 | if errorHandler == nil {
96 | errorHandler = defaultErrorHandler
97 | }
98 |
99 | return NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
100 | switch p.state {
101 | case Fulfilled, Rejected:
102 | if p.reason != nil {
103 | reject(errorHandler(p.reason))
104 | } else {
105 | resolve(successHandler(p.value))
106 | }
107 | }
108 | })
109 | }
110 |
111 | // Catch registers a callback to be called when the Promise is rejected
112 | // Catch 注册 Promise 被拒绝时要调用的回调函数
113 | func (p *Promise) Catch(errorHandler func(error) (interface{}, error)) *Promise {
114 | return p.Then(nil, errorHandler)
115 | }
116 |
117 | // Finally registers a cleanup callback to be called regardless of the Promise state
118 | // Finally 注册无论 Promise 状态如何都会调用的清理回调函数
119 | func (p *Promise) Finally(cleanupHandler func() error) *Promise {
120 | if cleanupHandler == nil {
121 | cleanupHandler = defaultCleanupHandler
122 | }
123 |
124 | return p.Then(
125 | func(value interface{}) (interface{}, error) {
126 | err := cleanupHandler()
127 | if err != nil {
128 | return nil, err
129 | }
130 | return value, nil
131 | },
132 | func(reason error) (interface{}, error) {
133 | err := cleanupHandler()
134 | if err != nil {
135 | return nil, err
136 | }
137 | return nil, reason
138 | },
139 | )
140 | }
141 |
142 | func (p *Promise) GetValue() interface{} {
143 | return p.value
144 | }
145 |
146 | func (p *Promise) GetReason() error {
147 | return p.reason
148 | }
149 |
150 | // All waits for all promises to be fulfilled
151 | // If any promise is rejected, the resulting promise is rejected
152 | // All 等待所有 Promise 完成
153 | // 如果任何一个 Promise 被拒绝,结果 Promise 也会被拒绝
154 | func All(promises ...*Promise) *Promise {
155 | return NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
156 | if len(promises) == 0 {
157 | resolve([]interface{}{}, nil)
158 | return
159 | }
160 |
161 | values := make([]interface{}, len(promises))
162 | pendingCount := len(promises)
163 | isCompleted := false
164 |
165 | for i, promise := range promises {
166 | promise.Then(func(value interface{}) (interface{}, error) {
167 | if !isCompleted {
168 | values[i] = value
169 | pendingCount--
170 | if pendingCount == 0 {
171 | resolve(values, nil)
172 | }
173 | }
174 | return nil, nil
175 | }, func(reason error) (interface{}, error) {
176 | if !isCompleted {
177 | isCompleted = true
178 | reject(nil, reason)
179 | }
180 | return nil, nil
181 | })
182 | }
183 | })
184 | }
185 |
186 | // AllSettled waits for all promises to settle, regardless of their state
187 | // AllSettled 等待所有 Promise 完成,无论其状态如何
188 | func AllSettled(promises ...*Promise) *Promise {
189 | return NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
190 | if len(promises) == 0 {
191 | resolve([]interface{}{}, nil)
192 | return
193 | }
194 |
195 | values := make([]interface{}, len(promises))
196 | pendingCount := len(promises)
197 |
198 | for i, promise := range promises {
199 | promise.Then(func(value interface{}) (interface{}, error) {
200 | values[i] = value
201 | pendingCount--
202 | if pendingCount == 0 {
203 | resolve(values, nil)
204 | }
205 | return nil, nil
206 | }, func(reason error) (interface{}, error) {
207 | values[i] = reason
208 | pendingCount--
209 | if pendingCount == 0 {
210 | resolve(values, nil)
211 | }
212 | return nil, nil
213 | })
214 | }
215 | })
216 | }
217 |
218 | // Any returns a promise that fulfills when any of the input promises fulfills
219 | // If all promises are rejected, returns an AggregateError
220 | // Any 返回一个在任意输入 Promise 成功时完成的 Promise
221 | // 如果所有 Promise 都被拒绝,返回一个 AggregateError
222 | func Any(promises ...*Promise) *Promise {
223 | return NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
224 | if len(promises) == 0 {
225 | reject(nil, NewAggregateError(0))
226 | return
227 | }
228 |
229 | errors := NewAggregateError(len(promises))
230 | pendingCount := len(promises)
231 | isCompleted := false
232 |
233 | for _, promise := range promises {
234 | promise.Then(func(value interface{}) (interface{}, error) {
235 | if !isCompleted {
236 | isCompleted = true
237 | resolve(value, nil)
238 | }
239 | return nil, nil
240 | }, func(reason error) (interface{}, error) {
241 | if !isCompleted {
242 | errors.Errors = append(errors.Errors, reason)
243 | pendingCount--
244 | if pendingCount == 0 {
245 | reject(nil, errors)
246 | }
247 | }
248 | return nil, nil
249 | })
250 | }
251 | })
252 | }
253 |
254 | // Race returns a promise that settles with the same state as the first settled promise
255 | // Race 返回一个与第一个完成的 Promise 具有相同状态的 Promise
256 | func Race(promises ...*Promise) *Promise {
257 | return NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
258 | if len(promises) == 0 {
259 | resolve(nil, nil)
260 | return
261 | }
262 |
263 | isCompleted := false
264 | for _, promise := range promises {
265 | promise.Then(func(value interface{}) (interface{}, error) {
266 | if !isCompleted {
267 | isCompleted = true
268 | resolve(value, nil)
269 | }
270 | return nil, nil
271 | }, func(reason error) (interface{}, error) {
272 | if !isCompleted {
273 | isCompleted = true
274 | reject(nil, reason)
275 | }
276 | return nil, nil
277 | })
278 | }
279 | })
280 | }
281 |
--------------------------------------------------------------------------------
/examples/case3/demo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 |
7 | vl "github.com/shengyanli1982/vowlink"
8 | )
9 |
10 | func main() {
11 |
12 | // 输出 "========== finally 1 successfully ==========" 到控制台
13 | // Print "========== finally 1 successfully ==========" to the console
14 | fmt.Println("========== finally 1 successfully ==========")
15 |
16 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
17 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
18 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
19 | // 这个 promise 直接解析为 "hello world"
20 | // This promise is directly resolved to "hello world"
21 | resolve("hello world", nil)
22 | }).Then(func(value interface{}) (interface{}, error) {
23 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
24 | // In the Then method, we append " vowlink !!" to the resolved value
25 | return value.(string) + " vowlink !!", nil
26 | }, nil).Catch(func(err error) (interface{}, error) {
27 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
28 | // If the promise is rejected, we return a new error message "rejected."
29 | return nil, fmt.Errorf("rejected.")
30 | }).Finally(func() error {
31 | // 不论 promise 是被解析还是被拒绝,Finally 方法都会被调用,并打印 "finally 1"
32 | // Whether the promise is resolved or rejected, the Finally method will be called and print "finally 1"
33 | fmt.Println("finally 1")
34 |
35 | // 返回 nil 表示 Finally 方法执行成功
36 | // Return nil indicates that the Finally method was executed successfully
37 | return nil
38 | })
39 |
40 | // 使用 Printf 函数输出 "finally 1 is called. value: %v, error: %v\n" 到控制台
41 | // 使用 result.GetValue() 和 result.GetReason() 作为 Printf 函数的参数
42 | // Use the Printf function to output "finally 1 is called. value: %v, error: %v\n" to the console
43 | // Use result.GetValue() and result.GetReason() as the parameters of the Printf function
44 | fmt.Printf("finally 1 is called. value: %v, error: %v\n", result.GetValue(), result.GetReason())
45 |
46 | // 输出 "========== finally 1 error ==========" 到控制台
47 | // Print "========== finally 1 error ==========" to the console
48 | fmt.Println("========== finally 1 error ==========")
49 |
50 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
51 | // 这个 promise 直接解析为 "hello world"
52 | // This promise is directly resolved to "hello world"
53 | resolve("hello world", nil)
54 | }).Then(func(value interface{}) (interface{}, error) {
55 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
56 | // In the Then method, we append " vowlink !!" to the resolved value
57 | return value.(string) + " vowlink !!", nil
58 | }, nil).Catch(func(err error) (interface{}, error) {
59 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
60 | // If the promise is rejected, we return a new error message "rejected."
61 | return nil, fmt.Errorf("rejected.")
62 | }).Finally(func() error {
63 | // Finally 函数会在 Promise 完成(无论解决还是拒绝)后被调用
64 | // The Finally function will be called after the Promise is settled (either resolved or rejected)
65 | fmt.Println("finally error: 1")
66 |
67 | // 返回一个新的错误 "error in finally 1"
68 | // Return a new error "error in finally 1"
69 | return errors.New("error in finally 1")
70 | }).Then(func(data interface{}) (interface{}, error) {
71 | // 当 Promise 被解决时,会执行这个 Then 函数
72 | // This Then function will be executed when the Promise is resolved
73 |
74 | // 返回解决的值,将会被下一个 Then 函数接收
75 | // Return the resolved value, which will be received by the next Then function
76 | return data.(string) + " vowlink", nil
77 | }, func(reason error) (interface{}, error) {
78 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
79 | // This Catch function will be executed when the Promise is rejected
80 |
81 | // 返回一个新的错误 "Handled error: " 加上原因的错误信息
82 | // Return a new error "Handled error: " plus the error message of the reason
83 | return nil, errors.New("Handled error: " + reason.Error())
84 | })
85 |
86 | // 使用 Printf 函数输出 "finally 1 error, but then is called. value: %v, error: %v\n" 到控制台
87 | // 使用 result.GetValue() 和 result.GetReason().Error() 作为 Printf 函数的参数
88 | // Use the Printf function to output "finally 1 error, but then is called. value: %v, error: %v\n" to the console
89 | // Use result.GetValue() and result.GetReason().Error() as the parameters of the Printf function
90 | fmt.Printf("finally 1 error, but then is called. value: %v, error: %v\n", result.GetValue(), result.GetReason().Error())
91 |
92 | // 输出 "========== finally 2 successfully ==========" 到控制台
93 | // Print "========== finally 2 successfully ==========" to the console
94 | fmt.Println("========== finally 2 successfully ==========")
95 |
96 | // 这是一个被拒绝的 promise
97 | // This is a rejected promise
98 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
99 | // 这个 promise 被拒绝,原因是 "error"
100 | // This promise is rejected with the reason "error"
101 | reject(nil, fmt.Errorf("error"))
102 | }).Then(func(value interface{}) (interface{}, error) {
103 | // 如果 promise 被解析,我们将解析的值加上 " vowlink !!"
104 | // If the promise is resolved, we append " vowlink !!" to the resolved value
105 | return value.(string) + " vowlink !!", nil
106 | }, nil).Catch(func(err error) (interface{}, error) {
107 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
108 | // If the promise is rejected, we return a new error message "rejected."
109 | return nil, fmt.Errorf("rejected.")
110 | }).Finally(func() error {
111 | // 不论 promise 是被解析还是被拒绝,Finally 方法都会被调用,并打印 "finally 2"
112 | // Whether the promise is resolved or rejected, the Finally method will be called and print "finally 2"
113 | fmt.Println("finally 2")
114 |
115 | // 返回 nil 表示 Finally 方法执行成功
116 | // Return nil indicates that the Finally method was executed successfully
117 | return nil
118 | })
119 |
120 | // 使用 Printf 函数输出 "finally 2 is called. value: %v, error: %v\n" 到控制台
121 | // 使用 result.GetValue() 和 result.GetReason() 作为 Printf 函数的参数
122 | // Use the Printf function to output "finally 2 is called. value: %v, error: %v\n" to the console
123 | // Use result.GetValue() and result.GetReason() as the parameters of the Printf function
124 | fmt.Printf("finally 2 is called. value: %v, error: %v\n", result.GetValue(), result.GetReason())
125 |
126 | // 输出 "========== finally 2 error ==========" 到控制台
127 | // Print "========== finally 2 error ==========" to the console
128 | fmt.Println("========== finally 2 error ==========")
129 |
130 | // 这是一个被拒绝的 promise,Finally 方法中返回了一个错误信息
131 | // This is a rejected promise, and an error message is returned in the Finally method
132 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
133 | // 这个 promise 被拒绝,原因是 "error"
134 | // This promise is rejected with the reason "error"
135 | reject(nil, fmt.Errorf("error"))
136 | }).Then(func(value interface{}) (interface{}, error) {
137 | // 如果 promise 被解析,我们将解析的值加上 " vowlink !!"
138 | // If the promise is resolved, we append " vowlink !!" to the resolved value
139 | return value.(string) + " vowlink !!", nil
140 | }, nil).Catch(func(err error) (interface{}, error) {
141 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
142 | // If the promise is rejected, we return a new error message "rejected."
143 | return nil, fmt.Errorf("rejected.")
144 | }).Finally(func() error {
145 | // Finally 函数会在 Promise 完成(无论解决还是拒绝)后被调用
146 | // The Finally function will be called after the Promise is settled (either resolved or rejected)
147 |
148 | // 输出 "finally error: 2" 到控制台
149 | // Print "finally error: 2" to the console
150 | fmt.Println("finally error: 2")
151 |
152 | // 返回一个新的错误 "error in finally 2"
153 | // Return a new error "error in finally 2"
154 | return errors.New("error in finally 2")
155 |
156 | }).Then(func(data interface{}) (interface{}, error) {
157 | // 当 Promise 被解决时,会执行这个 Then 函数
158 | // This Then function will be executed when the Promise is resolved
159 |
160 | // 返回解决的值,将会被下一个 Then 函数接收
161 | // Return the resolved value, which will be received by the next Then function
162 | return data.(string) + " vowlink", nil
163 | }, func(reason error) (interface{}, error) {
164 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
165 | // This Catch function will be executed when the Promise is rejected
166 |
167 | // 返回一个新的错误 "Handled error: " 加上原因的错误信息
168 | // Return a new error "Handled error: " plus the error message of the reason
169 | return nil, errors.New("Handled error: " + reason.Error())
170 | })
171 |
172 | // 使用 Printf 函数输出 "finally 2 error, but then is called. value: %v, error: %v\n" 到控制台
173 | // 使用 result.GetValue() 和 result.GetReason().Error() 作为 Printf 函数的参数
174 | // Use the Printf function to output "finally 2 error, but then is called. value: %v, error: %v\n" to the console
175 | // Use result.GetValue() and result.GetReason().Error() as the parameters of the Printf function
176 | fmt.Printf("finally 2 error, but then is called. value: %v, error: %v\n", result.GetValue(), result.GetReason().Error())
177 | }
178 |
--------------------------------------------------------------------------------
/promise_test.go:
--------------------------------------------------------------------------------
1 | package vowlink
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "testing"
7 | "time"
8 |
9 | "github.com/stretchr/testify/assert"
10 | )
11 |
12 | func TestPromise_Then(t *testing.T) {
13 | t.Run("Fulfilled state", func(t *testing.T) {
14 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
15 | resolve("Hello, World!", nil)
16 | })
17 |
18 | result := p.Then(func(value interface{}) (interface{}, error) {
19 | return value.(string) + " vowlink", nil
20 | }, nil)
21 |
22 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
23 | assert.Equal(t, "Hello, World! vowlink", result.value, "Expected value to be 'Hello, World! vowlink'")
24 | })
25 |
26 | t.Run("Rejected state", func(t *testing.T) {
27 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
28 | reject(nil, errors.New("Something went wrong"))
29 | })
30 |
31 | result := p.Then(nil, func(reason error) (interface{}, error) {
32 | return nil, errors.New("Handled error: " + reason.Error())
33 | })
34 |
35 | assert.Equal(t, Rejected, result.state, "Expected state to be Rejected")
36 | assert.Equal(t, "Handled error: Something went wrong", result.reason.Error(), "Expected reason to be 'Handled error: Something went wrong'")
37 | })
38 |
39 | t.Run("Nil onFulfilled and onRejected", func(t *testing.T) {
40 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
41 | resolve("Hello, World!", nil)
42 | })
43 |
44 | result := p.Then(nil, nil)
45 |
46 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
47 | assert.Equal(t, "Hello, World!", result.value, "Expected value to be 'Hello, World!'")
48 | })
49 |
50 | t.Run("Then Chain", func(t *testing.T) {
51 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
52 | resolve("Hello, World!", nil)
53 | })
54 |
55 | result := p.Then(func(value interface{}) (interface{}, error) {
56 | return value.(string) + " vowlink", nil
57 | }, nil).Then(func(value interface{}) (interface{}, error) {
58 | return value.(string) + "!", nil
59 | }, nil)
60 |
61 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
62 | assert.Equal(t, "Hello, World! vowlink!", result.value, "Expected value to be 'Hello, World! vowlink!'")
63 | })
64 |
65 | // 当.then中返回的不是promise对象时(包括undefined),p2的状态 一直都是fulfilled,且值为undefined
66 | t.Run("Then Chain with Rejection", func(t *testing.T) {
67 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
68 | resolve("Hello, World!", nil)
69 | })
70 |
71 | result := p.Then(func(value interface{}) (interface{}, error) {
72 | return value.(string) + " vowlink", nil
73 | }, nil).Then(func(value interface{}) (interface{}, error) {
74 | return value.(string) + "!", nil
75 | }, func(reason error) (interface{}, error) {
76 | return nil, errors.New("Handled error: " + reason.Error())
77 | })
78 |
79 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
80 | assert.Equal(t, "Hello, World! vowlink!", result.value, "Expected value to be 'Hello, World! vowlink!'")
81 | })
82 |
83 | t.Run("Then return a Promise with resolve", func(t *testing.T) {
84 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
85 | resolve("Hello, World!", nil)
86 | })
87 |
88 | result := p.Then(func(value interface{}) (interface{}, error) {
89 | return NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
90 | resolve(value.(string)+" vowlink", nil)
91 | }), nil
92 | }, nil)
93 |
94 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
95 | assert.Equal(t, "Hello, World! vowlink", result.value.(*Promise).GetValue(), "Expected value to be 'Hello, World! vowlink'")
96 | })
97 |
98 | t.Run("Then return a Promise with reject", func(t *testing.T) {
99 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
100 | resolve("Hello, World!", nil)
101 | })
102 |
103 | result := p.Then(func(value interface{}) (interface{}, error) {
104 | return NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
105 | reject(nil, errors.New("Something went wrong"))
106 | }), nil
107 | }, nil)
108 |
109 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
110 | assert.Equal(t, Rejected, result.value.(*Promise).state, "Expected value to be Rejected")
111 | assert.Equal(t, "Something went wrong", result.value.(*Promise).GetReason().Error(), "Expected reason to be 'Something went wrong'")
112 | })
113 |
114 | t.Run("One Then onRejected after Then return a Promise with reject", func(t *testing.T) {
115 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
116 | resolve("Hello, World!", nil)
117 | })
118 |
119 | result := p.Then(func(value interface{}) (interface{}, error) {
120 | return NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
121 | reject(nil, errors.New("Something went wrong"))
122 | }), nil
123 | }, nil).Then(nil, func(reason error) (interface{}, error) {
124 | return nil, errors.New("Handled error: " + reason.Error())
125 | })
126 |
127 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
128 | assert.Equal(t, "Something went wrong", result.value.(*Promise).reason.Error(), "Expected reason to be 'Something went wrong', Then(nil, func(reason error) error) not work")
129 | })
130 | }
131 |
132 | func TestPromise_Catch(t *testing.T) {
133 | t.Run("Fulfilled state", func(t *testing.T) {
134 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
135 | resolve("Hello, World!", nil)
136 | })
137 |
138 | result := p.Catch(func(reason error) (interface{}, error) {
139 | return nil, errors.New("Handled error: " + reason.Error())
140 | })
141 |
142 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
143 | assert.Equal(t, "Hello, World!", result.value, "Expected value to be 'Hello, World!'")
144 | })
145 |
146 | t.Run("Rejected state", func(t *testing.T) {
147 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
148 | reject(nil, errors.New("Something went wrong"))
149 | })
150 |
151 | result := p.Catch(func(reason error) (interface{}, error) {
152 | return nil, errors.New("Handled error: " + reason.Error())
153 | })
154 |
155 | assert.Equal(t, Rejected, result.state, "Expected state to be Fulfilled")
156 | assert.Equal(t, "Handled error: Something went wrong", result.reason.Error(), "Expected value to be 'Handled error: Something went wrong'")
157 | })
158 |
159 | t.Run("Nil onRejected", func(t *testing.T) {
160 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
161 | reject(nil, errors.New("Something went wrong"))
162 | })
163 |
164 | result := p.Catch(nil)
165 |
166 | assert.Equal(t, Rejected, result.state, "Expected state to be Fulfilled")
167 | assert.Equal(t, "Something went wrong", result.reason.Error(), "Expected value to be 'Something went wrong'")
168 | })
169 | }
170 |
171 | func TestPromise_Finally(t *testing.T) {
172 | t.Run("Fulfilled state", func(t *testing.T) {
173 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
174 | resolve("Hello, World!", nil)
175 | })
176 |
177 | var finallyCalled bool
178 | result := p.Finally(func() error {
179 | finallyCalled = true
180 | return nil
181 | })
182 |
183 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
184 | assert.Equal(t, "Hello, World!", result.value, "Expected value to be 'Hello, World!'")
185 | assert.True(t, finallyCalled, "Expected finally function to be called")
186 | })
187 |
188 | t.Run("Rejected state", func(t *testing.T) {
189 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
190 | reject(nil, errors.New("Something went wrong"))
191 | })
192 |
193 | var finallyCalled bool
194 | result := p.Finally(func() error {
195 | finallyCalled = true
196 | return nil
197 | })
198 |
199 | assert.Equal(t, Rejected, result.state, "Expected state to be Rejected")
200 | assert.Equal(t, "Something went wrong", result.reason.Error(), "Expected reason to be 'Something went wrong'")
201 | assert.True(t, finallyCalled, "Expected finally function to be called")
202 | })
203 |
204 | t.Run("Nil onFinally", func(t *testing.T) {
205 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
206 | resolve("Hello, World!", nil)
207 | })
208 |
209 | result := p.Finally(nil)
210 |
211 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
212 | assert.Equal(t, "Hello, World!", result.value, "Expected value to be 'Hello, World!'")
213 | })
214 | }
215 |
216 | func TestMethod_All(t *testing.T) {
217 | t.Run("All promises fulfilled", func(t *testing.T) {
218 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
219 | resolve("Promise 1", nil)
220 | })
221 |
222 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
223 | resolve("Promise 2", nil)
224 | })
225 |
226 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
227 | resolve("Promise 3", nil)
228 | })
229 |
230 | result := All(p1, p2, p3)
231 |
232 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
233 | assert.Equal(t, []interface{}{"Promise 1", "Promise 2", "Promise 3"}, result.value, "Expected value to be ['Promise 1', 'Promise 2', 'Promise 3']")
234 | })
235 |
236 | t.Run("One promise rejected", func(t *testing.T) {
237 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
238 | resolve("Promise 1", nil)
239 | })
240 |
241 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
242 | reject(nil, errors.New("Promise 2 rejected"))
243 | })
244 |
245 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
246 | resolve("Promise 3", nil)
247 | })
248 |
249 | result := All(p1, p2, p3)
250 |
251 | assert.Equal(t, Rejected, result.state, "Expected state to be Rejected")
252 | assert.Equal(t, "Promise 2 rejected", result.reason.Error(), "Expected reason to be 'Promise 2 rejected'")
253 | })
254 |
255 | t.Run("All promises rejected", func(t *testing.T) {
256 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
257 | reject(nil, errors.New("Promise 1 rejected"))
258 | })
259 |
260 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
261 | reject(nil, errors.New("Promise 2 rejected"))
262 | })
263 |
264 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
265 | reject(nil, errors.New("Promise 3 rejected"))
266 | })
267 |
268 | result := All(p1, p2, p3)
269 |
270 | assert.Equal(t, Rejected, result.state, "Expected state to be Rejected")
271 | assert.Equal(t, "Promise 1 rejected", result.reason.Error(), "Expected reason to be 'Promise 1 rejected'")
272 | })
273 | }
274 |
275 | func TestPromise_Any(t *testing.T) {
276 | t.Run("Any promises fulfilled", func(t *testing.T) {
277 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
278 | resolve("Promise 1", nil)
279 | })
280 |
281 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
282 | resolve("Promise 2", nil)
283 | })
284 |
285 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
286 | resolve("Promise 3", nil)
287 | })
288 |
289 | result := Any(p1, p2, p3)
290 |
291 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
292 | assert.Equal(t, "Promise 1", result.value, "Expected value to be 'Promise 1'")
293 | })
294 |
295 | t.Run("One promise rejected", func(t *testing.T) {
296 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
297 | resolve("Promise 1", nil)
298 | })
299 |
300 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
301 | reject(nil, errors.New("Promise 2 rejected"))
302 | })
303 |
304 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
305 | resolve("Promise 3", nil)
306 | })
307 |
308 | result := Any(p1, p2, p3)
309 |
310 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
311 | assert.Equal(t, "Promise 1", result.value, "Expected value to be 'Promise 1'")
312 | })
313 |
314 | t.Run("All promises rejected", func(t *testing.T) {
315 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
316 | reject(nil, errors.New("Promise 1 rejected"))
317 | })
318 |
319 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
320 | reject(nil, errors.New("Promise 2 rejected"))
321 | })
322 |
323 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
324 | reject(nil, errors.New("Promise 3 rejected"))
325 | })
326 |
327 | result := Any(p1, p2, p3)
328 |
329 | assert.Equal(t, Rejected, result.state, "Expected state to be Rejected")
330 | assert.Equal(t, &AggregateError{Errors: []error{errors.New("Promise 1 rejected"), errors.New("Promise 2 rejected"), errors.New("Promise 3 rejected")}}, result.reason, "Expected reason to be an AggregateError")
331 | })
332 | }
333 |
334 | func TestPromise_Race(t *testing.T) {
335 | t.Run("One promise fulfilled", func(t *testing.T) {
336 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
337 | resolve("Promise 1", nil)
338 | })
339 |
340 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
341 | resolve("Promise 2", nil)
342 | })
343 |
344 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
345 | resolve("Promise 3", nil)
346 | })
347 |
348 | result := Race(p1, p2, p3)
349 |
350 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
351 | assert.Equal(t, "Promise 1", result.value, "Expected value to be 'Promise 1'")
352 | })
353 |
354 | t.Run("One promise rejected", func(t *testing.T) {
355 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
356 | reject(nil, errors.New("Promise 1 rejected"))
357 | })
358 |
359 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
360 | resolve("Promise 2", nil)
361 | })
362 |
363 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
364 | resolve("Promise 3", nil)
365 | })
366 |
367 | result := Race(p1, p2, p3)
368 |
369 | assert.Equal(t, Rejected, result.state, "Expected state to be Rejected")
370 | assert.Equal(t, "Promise 1 rejected", result.reason.Error(), "Expected value to be 'Promise 1 rejected'")
371 | })
372 |
373 | t.Run("All promises rejected", func(t *testing.T) {
374 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
375 | reject(nil, errors.New("Promise 1 rejected"))
376 | })
377 |
378 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
379 | reject(nil, errors.New("Promise 2 rejected"))
380 | })
381 |
382 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
383 | reject(nil, errors.New("Promise 3 rejected"))
384 | })
385 |
386 | result := Race(p1, p2, p3)
387 |
388 | assert.Equal(t, Rejected, result.state, "Expected state to be Rejected")
389 | assert.Equal(t, "Promise 1 rejected", result.reason.Error(), "Expected reason to be 'Promise 1 rejected'")
390 | })
391 | }
392 |
393 | func TestPromise_AllSettled(t *testing.T) {
394 | t.Run("All promises fulfilled", func(t *testing.T) {
395 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
396 | resolve("Promise 1", nil)
397 | })
398 |
399 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
400 | resolve("Promise 2", nil)
401 | })
402 |
403 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
404 | resolve("Promise 3", nil)
405 | })
406 |
407 | result := AllSettled(p1, p2, p3)
408 |
409 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
410 | assert.Equal(t, []interface{}{"Promise 1", "Promise 2", "Promise 3"}, result.value, "Expected value to be ['Promise 1', 'Promise 2', 'Promise 3']")
411 | })
412 |
413 | t.Run("One promise rejected", func(t *testing.T) {
414 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
415 | resolve("Promise 1", nil)
416 | })
417 |
418 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
419 | reject(nil, errors.New("Promise 2 rejected"))
420 | })
421 |
422 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
423 | resolve("Promise 3", nil)
424 | })
425 |
426 | result := AllSettled(p1, p2, p3)
427 |
428 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
429 | assert.Equal(t, []interface{}{"Promise 1", errors.New("Promise 2 rejected"), "Promise 3"}, result.value, "Expected value to be ['Promise 1', errors.New('Promise 2 rejected'), 'Promise 3']")
430 | })
431 |
432 | t.Run("All promises rejected", func(t *testing.T) {
433 | p1 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
434 | reject(nil, errors.New("Promise 1 rejected"))
435 | })
436 |
437 | p2 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
438 | reject(nil, errors.New("Promise 2 rejected"))
439 | })
440 |
441 | p3 := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
442 | reject(nil, errors.New("Promise 3 rejected"))
443 | })
444 |
445 | result := AllSettled(p1, p2, p3)
446 |
447 | assert.Equal(t, Fulfilled, result.state, "Expected state to be Fulfilled")
448 | assert.Equal(t, []interface{}{errors.New("Promise 1 rejected"), errors.New("Promise 2 rejected"), errors.New("Promise 3 rejected")}, result.value, "Expected value to be [errors.New('Promise 1 rejected'), errors.New('Promise 2 rejected'), errors.New('Promise 3 rejected')]")
449 | })
450 | }
451 |
452 | func TestPromise_MultiCatch(t *testing.T) {
453 | t.Run("Rejected Multi Catch with New Error", func(t *testing.T) {
454 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
455 | reject(nil, errors.New("Something went wrong"))
456 | }).Catch(func(reason error) (interface{}, error) {
457 | return nil, errors.New("Handled 1 error: " + reason.Error())
458 | }).Catch(func(reason error) (interface{}, error) {
459 | return nil, errors.New("Handled 2 error: " + reason.Error())
460 | }).Catch(func(reason error) (interface{}, error) {
461 | return nil, errors.New("Handled 3 error: " + reason.Error())
462 | })
463 |
464 | assert.Equal(t, "Handled 3 error: Handled 2 error: Handled 1 error: Something went wrong", p.GetReason().Error(), "Expected reason to be 'Handled 3 error: Handled 2 error: Handled 1 error: Something went wrong'")
465 | assert.Nil(t, p.GetValue(), "Expected value to be nil")
466 | })
467 |
468 | t.Run("Rejected Multi Catch with Recover and Return Value", func(t *testing.T) {
469 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
470 | reject(nil, errors.New("Something went wrong"))
471 | }).Catch(func(reason error) (interface{}, error) {
472 | return nil, errors.New("Handled 1 error: " + reason.Error())
473 | }).Catch(func(reason error) (interface{}, error) {
474 | return "Recovered value", nil
475 | }).Then(func(data interface{}) (interface{}, error) {
476 | return data, nil
477 | }, nil)
478 |
479 | assert.Equal(t, "Recovered value", p.GetValue().(string), "Expected value to be 'Recovered value'")
480 | assert.Nil(t, p.GetReason(), "Expected reason to be nil")
481 | })
482 |
483 | t.Run("Rejected Multi Catch with Recover and Then return error", func(t *testing.T) {
484 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
485 | reject(nil, errors.New("Something went wrong"))
486 | }).Catch(func(reason error) (interface{}, error) {
487 | return nil, errors.New("Handled 1 error: " + reason.Error())
488 | }).Catch(func(reason error) (interface{}, error) {
489 | return "Recovered value", nil
490 | }).Then(func(data interface{}) (interface{}, error) {
491 | return nil, errors.New("Then error: " + data.(string))
492 | }, nil).Catch(func(reason error) (interface{}, error) {
493 | return nil, errors.New("Handled 2 error: " + reason.Error())
494 | })
495 |
496 | assert.Equal(t, "Handled 2 error: Then error: Recovered value", p.GetReason().Error(), "Expected reason to be 'Handled 2 error: Then error: Recovered value'")
497 | assert.Nil(t, p.GetValue(), "Expected value to be nil")
498 | })
499 |
500 | t.Run("Rejected Multi Catch with New Error and Finally", func(t *testing.T) {
501 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
502 | reject(nil, errors.New("Something went wrong"))
503 | }).Catch(func(reason error) (interface{}, error) {
504 | return nil, errors.New("Handled 1 error: " + reason.Error())
505 | }).Catch(func(reason error) (interface{}, error) {
506 | return nil, errors.New("Handled 2 error: " + reason.Error())
507 | }).Finally(func() error {
508 | fmt.Println("Finally called")
509 | return nil
510 | }).Catch(func(reason error) (interface{}, error) {
511 | return nil, errors.New("Handled 3 error: " + reason.Error())
512 | })
513 |
514 | assert.Equal(t, "Handled 3 error: Handled 2 error: Handled 1 error: Something went wrong", p.GetReason().Error(), "Expected reason to be 'Handled 3 error: Handled 2 error: Handled 1 error: Something went wrong'")
515 | assert.Nil(t, p.GetValue(), "Expected value to be nil")
516 | })
517 |
518 | t.Run("Rejected Multi Catch with Recover and Finally", func(t *testing.T) {
519 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
520 | reject(nil, errors.New("Something went wrong"))
521 | }).Catch(func(reason error) (interface{}, error) {
522 | return nil, errors.New("Handled 1 error: " + reason.Error())
523 | }).Catch(func(reason error) (interface{}, error) {
524 | return "Recovered value", nil
525 | }).Finally(func() error {
526 | fmt.Println("Finally called")
527 | return nil
528 | }).Then(func(data interface{}) (interface{}, error) {
529 | return data, nil
530 | }, nil)
531 |
532 | assert.Equal(t, "Recovered value", p.GetValue().(string), "Expected value to be 'Recovered value'")
533 | assert.Nil(t, p.GetReason(), "Expected reason to be nil")
534 | })
535 | }
536 |
537 | func TestPromise_ResolveWithError(t *testing.T) {
538 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
539 | resolve(nil, errors.New("Something went wrong"))
540 | }).Catch(func(reason error) (interface{}, error) {
541 | return nil, errors.New("Handled error: " + reason.Error())
542 | }).Catch(func(reason error) (interface{}, error) {
543 | return "Recovered value", nil
544 | }).Finally(func() error {
545 | fmt.Println("Finally called")
546 | return nil
547 | }).Then(func(data interface{}) (interface{}, error) {
548 | return data, nil
549 | }, nil)
550 |
551 | assert.Equal(t, "Recovered value", p.GetValue().(string), "Expected value to be 'Recovered value'")
552 | assert.Nil(t, p.GetReason(), "Expected reason to be nil")
553 | }
554 |
555 | func TestPromise_ResolveWithErrorData(t *testing.T) {
556 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
557 | resolve(errors.New("Something went wrong"), nil)
558 | }).Then(func(data interface{}) (interface{}, error) {
559 | return data.(error).Error(), nil
560 | }, func(error) (interface{}, error) {
561 | return nil, errors.New("Handled error")
562 | }).Catch(func(reason error) (interface{}, error) {
563 | return fmt.Sprintf("Recovered value: %v", reason.Error()), nil
564 | })
565 |
566 | assert.Equal(t, "Something went wrong", p.GetValue().(string), "Expected value to be 'Something went wrong'")
567 | assert.Nil(t, p.GetReason(), "Expected reason to be nil")
568 | }
569 |
570 | func TestPromise_RejectWithNil(t *testing.T) {
571 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
572 | reject("Something went wrong", nil)
573 | }).Then(func(data interface{}) (interface{}, error) {
574 | return data, nil
575 | }, func(error) (interface{}, error) {
576 | return nil, errors.New("Handled error")
577 | }).Catch(func(reason error) (interface{}, error) {
578 | return fmt.Sprintf("Recovered value: %v", reason.Error()), nil
579 | })
580 |
581 | assert.Equal(t, "Something went wrong", p.GetValue().(string), "Expected reason to be 'Something went wrong'")
582 | assert.Nil(t, p.GetReason(), "Expected value to be nil")
583 | }
584 |
585 | func TestPromise_FinallyWithError(t *testing.T) {
586 | t.Run("Finally with error and resolved", func(t *testing.T) {
587 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
588 | resolve("Hello, World!", nil)
589 | }).Finally(func() error {
590 | return errors.New("Finally error")
591 | }).Then(func(data interface{}) (interface{}, error) {
592 | return data.(string) + " vowlink", nil
593 | }, func(reason error) (interface{}, error) {
594 | return nil, errors.New("Handled error: " + reason.Error())
595 | })
596 |
597 | assert.Equal(t, "Handled error: Finally error", p.GetReason().Error(), "Expected reason to be 'Handled error: Finally error'")
598 | assert.Nil(t, p.GetValue(), "Expected value to be nil")
599 |
600 | })
601 |
602 | t.Run("Finally with error and rejected", func(t *testing.T) {
603 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
604 | reject(nil, errors.New("Something went wrong"))
605 | }).Finally(func() error {
606 | return errors.New("Finally error")
607 | }).Then(func(data interface{}) (interface{}, error) {
608 | return data.(string) + " vowlink", nil
609 | }, func(reason error) (interface{}, error) {
610 | return nil, errors.New("Handled error: " + reason.Error())
611 | })
612 |
613 | assert.Equal(t, "Handled error: Finally error", p.GetReason().Error(), "Expected reason to be 'Handled error: Finally error'")
614 | assert.Nil(t, p.GetValue(), "Expected value to be nil")
615 | })
616 | }
617 |
618 | func TestNewPromise(t *testing.T) {
619 | t.Run("nil handler", func(t *testing.T) {
620 | p := NewPromise(nil)
621 | assert.Nil(t, p, "Expected nil when handler is nil")
622 | })
623 |
624 | t.Run("initial state", func(t *testing.T) {
625 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
626 | // Empty handler
627 | })
628 | assert.Equal(t, Pending, p.state, "Expected initial state to be Pending")
629 | assert.Nil(t, p.value, "Expected initial value to be nil")
630 | assert.Nil(t, p.reason, "Expected initial reason to be nil")
631 | })
632 | }
633 |
634 | func TestPromise_ConcurrentAccess(t *testing.T) {
635 | t.Run("concurrent resolve/reject", func(t *testing.T) {
636 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
637 | go func() {
638 | resolve("success", nil)
639 | }()
640 | go func() {
641 | reject(nil, errors.New("error"))
642 | }()
643 | })
644 |
645 | // Wait for goroutines to complete
646 | time.Sleep(100 * time.Millisecond)
647 |
648 | // State should be either Fulfilled or Rejected, but not both
649 | assert.True(t, p.state == Fulfilled || p.state == Rejected,
650 | "Expected state to be either Fulfilled or Rejected")
651 | assert.True(t, (p.value == "success" && p.reason == nil) ||
652 | (p.value == nil && p.reason != nil),
653 | "Expected either value or reason to be set, not both")
654 | })
655 | }
656 |
657 | func TestPromise_StateImmutability(t *testing.T) {
658 | t.Run("fulfilled state cannot be changed", func(t *testing.T) {
659 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
660 | resolve("first", nil)
661 | resolve("second", nil) // should not change state
662 | reject(nil, errors.New("error")) // should not change state
663 | })
664 |
665 | assert.Equal(t, Fulfilled, p.state)
666 | assert.Equal(t, "first", p.value)
667 | assert.Nil(t, p.reason)
668 | })
669 |
670 | t.Run("rejected state cannot be changed", func(t *testing.T) {
671 | p := NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
672 | reject(nil, errors.New("first error"))
673 | reject(nil, errors.New("second error")) // should not change state
674 | resolve("success", nil) // should not change state
675 | })
676 |
677 | assert.Equal(t, Rejected, p.state)
678 | assert.Equal(t, "first error", p.reason.Error())
679 | assert.Nil(t, p.value)
680 | })
681 | }
682 |
683 | func TestPromise_EmptyArray(t *testing.T) {
684 | t.Run("All with empty array", func(t *testing.T) {
685 | result := All()
686 | assert.Equal(t, Fulfilled, result.state)
687 | assert.Equal(t, []interface{}{}, result.value)
688 | })
689 |
690 | t.Run("Race with empty array", func(t *testing.T) {
691 | result := Race()
692 | assert.Equal(t, Fulfilled, result.state)
693 | assert.Nil(t, result.value)
694 | })
695 |
696 | t.Run("Any with empty array", func(t *testing.T) {
697 | result := Any()
698 | assert.Equal(t, Rejected, result.state)
699 | assert.IsType(t, &AggregateError{}, result.reason)
700 | })
701 |
702 | t.Run("AllSettled with empty array", func(t *testing.T) {
703 | result := AllSettled()
704 | assert.Equal(t, Fulfilled, result.state)
705 | assert.Equal(t, []interface{}{}, result.value)
706 | })
707 | }
708 |
--------------------------------------------------------------------------------
/README_CN.md:
--------------------------------------------------------------------------------
1 | [English](./README.md) | 中文
2 |
3 |
4 |

5 |
6 |
7 | [](https://goreportcard.com/report/github.com/shengyanli1982/vowlink)
8 | [](https://github.com/shengyanli1982/vowlink/actions)
9 | [](https://pkg.go.dev/github.com/shengyanli1982/vowlink)
10 |
11 | ## 简介
12 |
13 | 想过向猫咪解释量子物理吗?解释 `VowLink` 可能同样具有挑战性!即使在完成第一个版本后,要找到完美的词语来描述这个优雅的解决方案,就像试图抓住激光笔的光点一样 —— 总是差那么一点点。
14 |
15 | 作为一名开发者,我经常遇到"回调地狱"的问题 —— 你懂的,就是那种代码看起来像埃及金字塔的 ASCII 艺术的时候。虽然 ES6 的 Promise 是个不错的解决方案,但我觉得在 Go 生态系统中还可以做得更好。于是,`VowLink` 诞生了 —— 这是一个 Promise 实现,让你的 Go 代码像热煎饼上的黄油一样顺滑。
16 |
17 | ## 优势
18 |
19 | - 简单得像派(用起来也一样美味)
20 | - 零依赖(有时候少即是多)
21 | - 完整的 Promise API 支持,包括 `then()`、`catch()`、`finally()`、`all()`、`race()`、`any()` 和 `allSettled()`(就像召开了一次完整的 Promise 家族聚会!)
22 |
23 | ## 安装
24 |
25 | ```bash
26 | go get github.com/shengyanli1982/vowlink
27 | ```
28 |
29 | ## 快速开始
30 |
31 | 使用 `VowLink` 比煮泡面还简单。来看看它能做什么:
32 |
33 | **示例**
34 |
35 | ```go
36 | package main
37 |
38 | import (
39 | "fmt"
40 | vl "github.com/shengyanli1982/vowlink"
41 | )
42 |
43 | func main() {
44 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
45 | resolve("hello world", nil)
46 | }).Then(func(value interface{}) (interface{}, error) {
47 | return value.(string) + " vowlink", nil
48 | }, nil).Then(func(value interface{}) (interface{}, error) {
49 | return value.(string) + " !!", nil
50 | }, nil)
51 |
52 | fmt.Println(result.GetValue())
53 | }
54 | ```
55 |
56 | **运行结果**
57 |
58 | ```bash
59 | $ go run demo.go
60 | hello world vowlink !!
61 | ```
62 |
63 | 看到了吧?比刚蒸好的小笼包还要顺滑!
64 |
65 | 与其用那些会让咖啡都睡着的理论例子,不如直接看一些实际场景。这些实用的例子会让你看到 `VowLink` 如何让你的代码跳起舞来。
66 |
67 | ### 核心规则
68 |
69 | > [!IMPORTANT]
70 | >
71 | > 在我们开始之前,这里是 `VowLink` 的黄金法则 —— 就当它是 Go 中 Promise 处理的"十诫"吧。
72 |
73 | 1. 所有的 `Then`、`Catch` 和 `Finally` 方法都可以返回错误。就像打热土豆游戏,这些错误会在链条中继续传递,直到有人妥善处理它们(返回 nil)。
74 | 2. `resolve` 和 `reject` 方法支持同时返回数据和错误,让 `NewPromise` 像瑜伽大师一样灵活。
75 | 3. `GetValue` 和 `GetReason` 是终结方法 —— 就像句子末尾的句号。一旦调用,它们就不会返回 Promise 对象。
76 | 4. 虽然 `VowLink` 从 JavaScript Promises 获取灵感,但它就像一套定制西装一样,专门为 Go 量身打造。
77 | 5. 不要在 `Then()`、`Catch()` 或 `Finally()` 方法中使用 goroutines。如果需要异步操作,就把整个 Promise 包装在一个 goroutine 中 —— 就像把整桌麻将搬到隔壁房间打一样,该有的规矩一个都不能少。
78 |
79 | ### 实例案例
80 |
81 | 我们的工作中有各种各样的案例,我将展示一些例子。您可以在 `examples` 目录中找到每个案例的代码。例如,案例 1 位于 `examples/case1`。
82 |
83 | #### 案例 1
84 |
85 | 就像在我们的代码中使用 `if` 和 `else` 一样,我们经常希望在条件为真时执行某些操作,在条件为假时执行不同的操作。
86 |
87 | **示例**
88 |
89 | ```go
90 | package main
91 |
92 | import (
93 | "fmt"
94 |
95 | vl "github.com/shengyanli1982/vowlink"
96 | )
97 |
98 | func main() {
99 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
100 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
101 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
102 | // 这个 promise 直接解析为 "hello world"
103 | // This promise is directly resolved to "hello world"
104 | resolve("hello world", nil)
105 | }).Then(func(value interface{}) (interface{}, error) {
106 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
107 | // In the Then method, we append " vowlink !!" to the resolved value
108 | return value.(string) + " vowlink !!", nil
109 | }, func(err error) (interface{}, error) {
110 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
111 | // If the promise is rejected, we return a new error message "rejected."
112 | return nil, fmt.Errorf("rejected.")
113 | })
114 |
115 | // 从 promise 中获取值并打印
116 | // Get the value from the promise and print it
117 | fmt.Println("Resolve:", result.GetValue())
118 |
119 | // 这是一个被拒绝的 promise
120 | // This is a rejected promise
121 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
122 | // 这个 promise 被拒绝,原因是 "error"
123 | // This promise is rejected with the reason "error"
124 | reject(nil, fmt.Errorf("error"))
125 | }).Then(func(value interface{}) (interface{}, error) {
126 | // 如果 promise 被解析,我们将解析的值加上 " vowlink"
127 | // If the promise is resolved, we append " vowlink" to the resolved value
128 | return value.(string) + " vowlink", nil
129 | }, func(err error) (interface{}, error) {
130 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
131 | // If the promise is rejected, we return a new error message "rejected."
132 | return nil, fmt.Errorf("rejected.")
133 | })
134 |
135 | // 从 promise 中获取拒绝的原因并打印
136 | // Get the reason for the rejection from the promise and print it
137 | fmt.Println("Rejected:", result.GetReason().Error())
138 | }
139 | ```
140 |
141 | **执行结果**
142 |
143 | ```bash
144 | $ go run demo.go
145 | Resolve: hello world vowlink !!
146 | Rejected: rejected.
147 | ```
148 |
149 | #### # 案例 2
150 |
151 | 我更喜欢在 Golang 中使用类似 JavaScript 风格的代码。我想使用 `then()` 在 promise 解析后执行操作,并使用 `catch()` 处理被拒绝的 promise。
152 |
153 | **示例**
154 |
155 | ```go
156 | package main
157 |
158 | import (
159 | "fmt"
160 |
161 | vl "github.com/shengyanli1982/vowlink"
162 | )
163 |
164 | func main() {
165 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
166 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
167 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
168 | // 这个 promise 直接解析为 "hello world"
169 | // This promise is directly resolved to "hello world"
170 | resolve("hello world", nil)
171 | }).Then(func(value interface{}) (interface{}, error) {
172 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
173 | // In the Then method, we append " vowlink !!" to the resolved value
174 | return value.(string) + " vowlink !!", nil
175 | }, nil).Catch(func(err error) (interface{}, error) {
176 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
177 | // If the promise is rejected, we return a new error message "rejected."
178 | return nil, fmt.Errorf("rejected.")
179 | })
180 |
181 | // 从 promise 中获取值并打印
182 | // Get the value from the promise and print it
183 | fmt.Println("Resolve:", result.GetValue())
184 |
185 | // 这是一个被拒绝的 promise
186 | // This is a rejected promise
187 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
188 | // 这个 promise 被拒绝,原因是 "error"
189 | // This promise is rejected with the reason "error"
190 | reject(nil, fmt.Errorf("error"))
191 | }).Then(func(value interface{}) (interface{}, error) {
192 | // 如果 promise 被解析,我们将解析的值加上 " vowlink !!"
193 | // If the promise is resolved, we append " vowlink !!" to the resolved value
194 | return value.(string) + " vowlink !!", nil
195 | }, nil).Catch(func(err error) (interface{}, error) {
196 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
197 | // If the promise is rejected, we return a new error message "rejected."
198 | return nil, fmt.Errorf("rejected.")
199 | })
200 |
201 | // 从 promise 中获取拒绝的原因并打印
202 | // Get the reason for the rejection from the promise and print it
203 | fmt.Println("Rejected:", result.GetReason().Error())
204 | }
205 | ```
206 |
207 | **执行结果**
208 |
209 | ```bash
210 | $ go run demo.go
211 | Resolve: hello world vowlink !!
212 | Rejected: rejected.
213 | ```
214 |
215 | #### # 案例 3
216 |
217 | 我想使用 `finally()` 在 promise 解析或被拒绝后执行一些操作。
218 |
219 | **示例**
220 |
221 | ```go
222 | package main
223 |
224 | import (
225 | "errors"
226 | "fmt"
227 |
228 | vl "github.com/shengyanli1982/vowlink"
229 | )
230 |
231 | func main() {
232 |
233 | // 输出 "========== finally 1 successfully ==========" 到控制台
234 | // Print "========== finally 1 successfully ==========" to the console
235 | fmt.Println("========== finally 1 successfully ==========")
236 |
237 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
238 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
239 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
240 | // 这个 promise 直接解析为 "hello world"
241 | // This promise is directly resolved to "hello world"
242 | resolve("hello world", nil)
243 | }).Then(func(value interface{}) (interface{}, error) {
244 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
245 | // In the Then method, we append " vowlink !!" to the resolved value
246 | return value.(string) + " vowlink !!", nil
247 | }, nil).Catch(func(err error) (interface{}, error) {
248 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
249 | // If the promise is rejected, we return a new error message "rejected."
250 | return nil, fmt.Errorf("rejected.")
251 | }).Finally(func() error {
252 | // 不论 promise 是被解析还是被拒绝,Finally 方法都会被调用,并打印 "finally 1"
253 | // Whether the promise is resolved or rejected, the Finally method will be called and print "finally 1"
254 | fmt.Println("finally 1")
255 |
256 | // 返回 nil 表示 Finally 方法执行成功
257 | // Return nil indicates that the Finally method was executed successfully
258 | return nil
259 | })
260 |
261 | // 使用 Printf 函数输出 "finally 1 is called. value: %v, error: %v\n" 到控制台
262 | // 使用 result.GetValue() 和 result.GetReason() 作为 Printf 函数的参数
263 | // Use the Printf function to output "finally 1 is called. value: %v, error: %v\n" to the console
264 | // Use result.GetValue() and result.GetReason() as the parameters of the Printf function
265 | fmt.Printf("finally 1 is called. value: %v, error: %v\n", result.GetValue(), result.GetReason())
266 |
267 | // 输出 "========== finally 1 error ==========" 到控制台
268 | // Print "========== finally 1 error ==========" to the console
269 | fmt.Println("========== finally 1 error ==========")
270 |
271 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
272 | // 这个 promise 直接解析为 "hello world"
273 | // This promise is directly resolved to "hello world"
274 | resolve("hello world", nil)
275 | }).Then(func(value interface{}) (interface{}, error) {
276 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
277 | // In the Then method, we append " vowlink !!" to the resolved value
278 | return value.(string) + " vowlink !!", nil
279 | }, nil).Catch(func(err error) (interface{}, error) {
280 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
281 | // If the promise is rejected, we return a new error message "rejected."
282 | return nil, fmt.Errorf("rejected.")
283 | }).Finally(func() error {
284 | // Finally 函数会在 Promise 完成(无论解决还是拒绝)后被调用
285 | // The Finally function will be called after the Promise is settled (either resolved or rejected)
286 | fmt.Println("finally error: 1")
287 |
288 | // 返回一个新的错误 "error in finally 1"
289 | // Return a new error "error in finally 1"
290 | return errors.New("error in finally 1")
291 | }).Then(func(data interface{}) (interface{}, error) {
292 | // 当 Promise 被解决时,会执行这个 Then 函数
293 | // This Then function will be executed when the Promise is resolved
294 |
295 | // 返回解决的值,将会被下一个 Then 函数接收
296 | // Return the resolved value, which will be received by the next Then function
297 | return data.(string) + " vowlink", nil
298 | }, func(reason error) (interface{}, error) {
299 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
300 | // This Catch function will be executed when the Promise is rejected
301 |
302 | // 返回一个新的错误 "Handled error: " 加上原因的错误信息
303 | // Return a new error "Handled error: " plus the error message of the reason
304 | return nil, errors.New("Handled error: " + reason.Error())
305 | })
306 |
307 | // 使用 Printf 函数输出 "finally 1 error, but then is called. value: %v, error: %v\n" 到控制台
308 | // 使用 result.GetValue() 和 result.GetReason().Error() 作为 Printf 函数的参数
309 | // Use the Printf function to output "finally 1 error, but then is called. value: %v, error: %v\n" to the console
310 | // Use result.GetValue() and result.GetReason().Error() as the parameters of the Printf function
311 | fmt.Printf("finally 1 error, but then is called. value: %v, error: %v\n", result.GetValue(), result.GetReason().Error())
312 |
313 | // 输出 "========== finally 2 successfully ==========" 到控制台
314 | // Print "========== finally 2 successfully ==========" to the console
315 | fmt.Println("========== finally 2 successfully ==========")
316 |
317 | // 这是一个被拒绝的 promise
318 | // This is a rejected promise
319 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
320 | // 这个 promise 被拒绝,原因是 "error"
321 | // This promise is rejected with the reason "error"
322 | reject(nil, fmt.Errorf("error"))
323 | }).Then(func(value interface{}) (interface{}, error) {
324 | // 如果 promise 被解析,我们将解析的值加上 " vowlink !!"
325 | // If the promise is resolved, we append " vowlink !!" to the resolved value
326 | return value.(string) + " vowlink !!", nil
327 | }, nil).Catch(func(err error) (interface{}, error) {
328 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
329 | // If the promise is rejected, we return a new error message "rejected."
330 | return nil, fmt.Errorf("rejected.")
331 | }).Finally(func() error {
332 | // 不论 promise 是被解析还是被拒绝,Finally 方法都会被调用,并打印 "finally 2"
333 | // Whether the promise is resolved or rejected, the Finally method will be called and print "finally 2"
334 | fmt.Println("finally 2")
335 |
336 | // 返回 nil 表示 Finally 方法执行成功
337 | // Return nil indicates that the Finally method was executed successfully
338 | return nil
339 | })
340 |
341 | // 使用 Printf 函数输出 "finally 2 is called. value: %v, error: %v\n" 到控制台
342 | // 使用 result.GetValue() 和 result.GetReason() 作为 Printf 函数的参数
343 | // Use the Printf function to output "finally 2 is called. value: %v, error: %v\n" to the console
344 | // Use result.GetValue() and result.GetReason() as the parameters of the Printf function
345 | fmt.Printf("finally 2 is called. value: %v, error: %v\n", result.GetValue(), result.GetReason())
346 |
347 | // 输出 "========== finally 2 error ==========" 到控制台
348 | // Print "========== finally 2 error ==========" to the console
349 | fmt.Println("========== finally 2 error ==========")
350 |
351 | // 这是一个被拒绝的 promise,Finally 方法中返回了一个错误信息
352 | // This is a rejected promise, and an error message is returned in the Finally method
353 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
354 | // 这个 promise 被拒绝,原因是 "error"
355 | // This promise is rejected with the reason "error"
356 | reject(nil, fmt.Errorf("error"))
357 | }).Then(func(value interface{}) (interface{}, error) {
358 | // 如果 promise 被解析,我们将解析的值加上 " vowlink !!"
359 | // If the promise is resolved, we append " vowlink !!" to the resolved value
360 | return value.(string) + " vowlink !!", nil
361 | }, nil).Catch(func(err error) (interface{}, error) {
362 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
363 | // If the promise is rejected, we return a new error message "rejected."
364 | return nil, fmt.Errorf("rejected.")
365 | }).Finally(func() error {
366 | // Finally 函数会在 Promise 完成(无论解决还是拒绝)后被调用
367 | // The Finally function will be called after the Promise is settled (either resolved or rejected)
368 |
369 | // 输出 "finally error: 2" 到控制台
370 | // Print "finally error: 2" to the console
371 | fmt.Println("finally error: 2")
372 |
373 | // 返回一个新的错误 "error in finally 2"
374 | // Return a new error "error in finally 2"
375 | return errors.New("error in finally 2")
376 |
377 | }).Then(func(data interface{}) (interface{}, error) {
378 | // 当 Promise 被解决时,会执行这个 Then 函数
379 | // This Then function will be executed when the Promise is resolved
380 |
381 | // 返回解决的值,将会被下一个 Then 函数接收
382 | // Return the resolved value, which will be received by the next Then function
383 | return data.(string) + " vowlink", nil
384 | }, func(reason error) (interface{}, error) {
385 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
386 | // This Catch function will be executed when the Promise is rejected
387 |
388 | // 返回一个新的错误 "Handled error: " 加上原因的错误信息
389 | // Return a new error "Handled error: " plus the error message of the reason
390 | return nil, errors.New("Handled error: " + reason.Error())
391 | })
392 |
393 | // 使用 Printf 函数输出 "finally 2 error, but then is called. value: %v, error: %v\n" 到控制台
394 | // 使用 result.GetValue() 和 result.GetReason().Error() 作为 Printf 函数的参数
395 | // Use the Printf function to output "finally 2 error, but then is called. value: %v, error: %v\n" to the console
396 | // Use result.GetValue() and result.GetReason().Error() as the parameters of the Printf function
397 | fmt.Printf("finally 2 error, but then is called. value: %v, error: %v\n", result.GetValue(), result.GetReason().Error())
398 | }
399 | ```
400 |
401 | **执行结果**
402 |
403 | ```bash
404 | $ go run demo.go
405 | ========== finally 1 successfully ==========
406 | finally 1
407 | finally 1 is called. value: hello world vowlink !!, error:
408 | ========== finally 1 error ==========
409 | finally error: 1
410 | finally 1 error, but then is called. value: , error: Handled error: error in finally 1
411 | ========== finally 2 successfully ==========
412 | finally 2
413 | finally 2 is called. value: , error: rejected.
414 | ========== finally 2 error ==========
415 | finally error: 2
416 | finally 2 error, but then is called. value: , error: Handled error: error in finally 2
417 | ```
418 |
419 | #### # 案例 4
420 |
421 | 是的,你可以使用 `then()` 方法返回一个新的 promise。
422 |
423 | **示例**
424 |
425 | ```go
426 | package main
427 |
428 | import (
429 | "fmt"
430 |
431 | vl "github.com/shengyanli1982/vowlink"
432 | )
433 |
434 | func main() {
435 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
436 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
437 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
438 | // 这个 promise 直接解析为 "hello world"
439 | // This promise is directly resolved to "hello world"
440 | resolve("hello world", nil)
441 | }).Then(func(value interface{}) (interface{}, error) {
442 | // 在 Then 方法中,我们创建一个新的 promise,将解析的值加上 " vowlink(NewPromise)"
443 | // In the Then method, we create a new promise, appending " vowlink(NewPromise)" to the resolved value
444 | return vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
445 | resolve(value.(string)+" vowlink(NewPromise)", nil)
446 | }), nil
447 | }, nil).Then(func(value interface{}) (interface{}, error) {
448 | // 在这个 Then 方法中,我们获取前一个 promise 的值,并加上 " !!"
449 | // In this Then method, we get the value from the previous promise and append " !!"
450 | return value.(*vl.Promise).GetValue().(string) + " !!", nil
451 | }, nil)
452 |
453 | // 从 promise 中获取值并打印
454 | // Get the value from the promise and print it
455 | fmt.Println(result.GetValue())
456 | }
457 | ```
458 |
459 | **执行结果**
460 |
461 | ```bash
462 | $ go run demo.go
463 | hello world vowlink(NewPromise) !!
464 | ```
465 |
466 | #### # 案例 5
467 |
468 | 如果要在所有 promise 解析后执行某个操作,可以使用 `all()` 方法。
469 |
470 | **示例**
471 |
472 | ```go
473 | package main
474 |
475 | import (
476 | "fmt"
477 |
478 | vl "github.com/shengyanli1982/vowlink"
479 | )
480 |
481 | func main() {
482 | // 创建 3 个 promise
483 | // Create 3 promises
484 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
485 | // 第一个 promise 直接解析为 "Promise"
486 | // The first promise is directly resolved to "Promise"
487 | resolve("Promise", nil)
488 | }).Then(func(value interface{}) (interface{}, error) {
489 | // 在 Then 方法中,将解析的值加上 " 1"
490 | // In the Then method, append " 1" to the resolved value
491 | return value.(string) + " 1", nil
492 | }, nil)
493 |
494 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
495 | // 第二个 promise 直接解析为 "Promise"
496 | // The second promise is directly resolved to "Promise"
497 | resolve("Promise", nil)
498 | }).Then(func(value interface{}) (interface{}, error) {
499 | // 在 Then 方法中,将解析的值加上 " 2"
500 | // In the Then method, append " 2" to the resolved value
501 | return value.(string) + " 2", nil
502 | }, nil)
503 |
504 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
505 | // 第三个 promise 直接解析为 "Promise"
506 | // The third promise is directly resolved to "Promise"
507 | resolve("Promise", nil)
508 | }).Then(func(value interface{}) (interface{}, error) {
509 | // 在 Then 方法中,将解析的值加上 " 3"
510 | // In the Then method, append " 3" to the resolved value
511 | return value.(string) + " 3", nil
512 | }, nil)
513 |
514 | // All() 将等待所有的 promise 被解析,并返回一个带有所有值的 promise
515 | // All() will wait for all promises to be resolved, and return a promise with all the values
516 | result := vl.All(p1, p2, p3)
517 |
518 | // 从 promise 中获取所有的值并打印
519 | // Get all the values from the promise and print them
520 | for i, str := range result.GetValue().([]interface{}) {
521 | fmt.Println(">>", i, str.(string))
522 | }
523 | }
524 | ```
525 |
526 | **执行结果**
527 |
528 | ```bash
529 | $ go run demo.go
530 | >> 0 Promise 1
531 | >> 1 Promise 2
532 | >> 2 Promise 3
533 | ```
534 |
535 | #### # 案例 6
536 |
537 | 我想使用 `race()` 在第一个 promise 解析后执行某个操作。
538 |
539 | **示例**
540 |
541 | ```go
542 | package main
543 |
544 | import (
545 | "fmt"
546 |
547 | vl "github.com/shengyanli1982/vowlink"
548 | )
549 |
550 | func main() {
551 | // 创建 3 个 promise
552 | // Create 3 promises
553 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
554 | // 第一个 promise 直接解析为 "Promise"
555 | // The first promise is directly resolved to "Promise"
556 | resolve("Promise", nil)
557 | }).Then(func(value interface{}) (interface{}, error) {
558 | // 在 Then 方法中,将解析的值加上 " 1"
559 | // In the Then method, append " 1" to the resolved value
560 | return value.(string) + " 1", nil
561 | }, nil)
562 |
563 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
564 | // 第二个 promise 直接解析为 "Promise"
565 | // The second promise is directly resolved to "Promise"
566 | resolve("Promise", nil)
567 | }).Then(func(value interface{}) (interface{}, error) {
568 | // 在 Then 方法中,将解析的值加上 " 2"
569 | // In the Then method, append " 2" to the resolved value
570 | return value.(string) + " 2", nil
571 | }, nil)
572 |
573 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
574 | // 第三个 promise 直接解析为 "Promise"
575 | // The third promise is directly resolved to "Promise"
576 | resolve("Promise", nil)
577 | }).Then(func(value interface{}) (interface{}, error) {
578 | // 在 Then 方法中,将解析的值加上 " 3"
579 | // In the Then method, append " 3" to the resolved value
580 | return value.(string) + " 3", nil
581 | }, nil)
582 |
583 | // Race() 将等待第一个 promise 被解析,并返回一个带有值的 promise
584 | // Race() will wait for the first promise to be resolved, and return a promise with the value
585 | result := vl.Race(p1, p2, p3)
586 |
587 | // 从 promise 中获取值并打印
588 | // Get the value from the promise and print it
589 | fmt.Println(">>", result.GetValue().(string))
590 | }
591 | ```
592 |
593 | **执行结果**
594 |
595 | ```bash
596 | $ go run demo.go
597 | >> Promise 1
598 | ```
599 |
600 | #### # 案例 7
601 |
602 | 我想使用 `any()` 在第一个 promise 解析后执行某个操作。`any()` 类似于 ES6 中的 `race`。然而,`any()` 还会捕获所有 promise 的错误,并在所有 promise 都被拒绝时返回一个 `AggregateError`。
603 |
604 | **示例**
605 |
606 | ```go
607 | package main
608 |
609 | import (
610 | "errors"
611 | "fmt"
612 |
613 | vl "github.com/shengyanli1982/vowlink"
614 | )
615 |
616 | func main() {
617 | // 创建 3 个 promise
618 | // Create 3 promises
619 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
620 | // 第一个 promise 直接解析为 "Promise"
621 | // The first promise is directly resolved to "Promise"
622 | resolve("Promise", nil)
623 | }).Then(func(value interface{}) (interface{}, error) {
624 | // 在 Then 方法中,将解析的值加上 " 1"
625 | // In the Then method, append " 1" to the resolved value
626 | return value.(string) + " 1", nil
627 | }, nil)
628 |
629 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
630 | // 第二个 promise 直接解析为 "Promise"
631 | // The second promise is directly resolved to "Promise"
632 | resolve("Promise", nil)
633 | }).Then(func(value interface{}) (interface{}, error) {
634 | // 在 Then 方法中,将解析的值加上 " 2"
635 | // In the Then method, append " 2" to the resolved value
636 | return value.(string) + " 2", nil
637 | }, nil)
638 |
639 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
640 | // 第三个 promise 直接解析为 "Promise"
641 | // The third promise is directly resolved to "Promise"
642 | resolve("Promise", nil)
643 | }).Then(func(value interface{}) (interface{}, error) {
644 | // 在 Then 方法中,将解析的值加上 " 3"
645 | // In the Then method, append " 3" to the resolved value
646 | return value.(string) + " 3", nil
647 | }, nil)
648 |
649 | // Any() 将等待第一个 promise 被解析,并返回一个带有值的 promise
650 | // Any() will wait for the first promise to be resolved, and return a promise with the value
651 | result := vl.Any(p1, p2, p3)
652 |
653 | // 从 promise 中获取值并打印
654 | // Get the value from the promise and print it
655 | fmt.Println(">>", result.GetValue().(string))
656 |
657 | // 创建 3 个 promise
658 | // Create 3 promises
659 | p1 = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
660 | // 第一个 promise 被拒绝,原因是 "Promise 1 rejected"
661 | // The first promise is rejected with the reason "Promise 1 rejected"
662 | reject(nil, errors.New("Promise 1 rejected"))
663 | })
664 |
665 | p2 = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
666 | // 第二个 promise 被拒绝,原因是 "Promise 2 rejected"
667 | // The second promise is rejected with the reason "Promise 2 rejected"
668 | reject(nil, errors.New("Promise 2 rejected"))
669 | })
670 |
671 | p3 = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
672 | // 第三个 promise 被拒绝,原因是 "Promise 3 rejected"
673 | // The third promise is rejected with the reason "Promise 3 rejected"
674 | reject(nil, errors.New("Promise 3 rejected"))
675 | })
676 |
677 | // Any() 将等待所有的 promise 被拒绝,并返回一个带有原因 `AggregateError` 的 promise
678 | // Any() will wait for all promises to be rejected, and return a promise with the reason `AggregateError`
679 | result = vl.Any(p1, p2, p3)
680 |
681 | // 从 promise 中获取原因并打印
682 | // Get the reason from the promise and print it
683 | fmt.Println("!!", result.GetReason().Error())
684 | }
685 | ```
686 |
687 | **执行结果**
688 |
689 | ```bash
690 | $ go run demo.go
691 | >> Promise 1
692 | !! All promises were rejected: Promise 1 rejected, Promise 2 rejected, Promise 3 rejected
693 | ```
694 |
695 | #### # 案例 8
696 |
697 | 要在所有 promise 解析或拒绝后执行操作,可以使用 `allSettled()` 方法。
698 |
699 | **示例**
700 |
701 | ```go
702 | package main
703 |
704 | import (
705 | "errors"
706 | "fmt"
707 |
708 | vl "github.com/shengyanli1982/vowlink"
709 | )
710 |
711 | func main() {
712 | // 创建 3 个 promise
713 | // Create 3 promises
714 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
715 | // 第一个 promise 直接解析为 "Promise 1"
716 | // The first promise is directly resolved to "Promise 1"
717 | resolve("Promise 1", nil)
718 | })
719 |
720 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
721 | // 第二个 promise 被拒绝,原因是 "Promise 2 rejected"
722 | // The second promise is rejected with the reason "Promise 2 rejected"
723 | reject(nil, errors.New("Promise 2 rejected"))
724 | })
725 |
726 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
727 | // 第三个 promise 直接解析为 "Promise 3"
728 | // The third promise is directly resolved to "Promise 3"
729 | resolve("Promise 3", nil)
730 | })
731 |
732 | // AllSettled() 将等待所有的 promise 被解析或拒绝,并返回一个带有值的 promise
733 | // AllSettled() will wait for all promises to be resolved or rejected, and return a promise with the value
734 | result := vl.AllSettled(p1, p2, p3)
735 |
736 | // 从 promise 中获取所有的结果
737 | // Get all the results from the promise
738 | for i, r := range result.GetValue().([]interface{}) {
739 | // 如果结果是一个错误,打印错误信息
740 | // If the result is an error, print the error message
741 | if v, ok := r.(error); ok {
742 | fmt.Println("!!", i, v.Error())
743 | } else {
744 | // 否则,打印结果值
745 | // Otherwise, print the result value
746 | fmt.Println(">>", i, r.(string))
747 | }
748 | }
749 | }
750 | ```
751 |
752 | **执行结果**
753 |
754 | ```bash
755 | $ go run demo.go
756 | >> 0 Promise 1
757 | !! 1 Promise 2 rejected
758 | >> 2 Promise 3
759 | ```
760 |
761 | #### # 案例 9
762 |
763 | 在创建 Promise 对象后,您可以使用 `reject` 函数触发一个错误。后续的 `catch()` 函数将处理前一个错误并返回一个新的错误,从而创建一个错误调用链。
764 |
765 | **示例**
766 |
767 | ```go
768 | package main
769 |
770 | import (
771 | "errors"
772 | "fmt"
773 |
774 | vl "github.com/shengyanli1982/vowlink"
775 | )
776 |
777 | func main() {
778 |
779 | // 创建一个新的 Promise
780 | // Create a new Promise
781 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
782 | // 这个 Promise 会立即被拒绝,原因是 "rejected.100"
783 | // This Promise will be immediately rejected with the reason "rejected.100"
784 | reject(nil, fmt.Errorf("rejected.100"))
785 |
786 | }).Catch(func(err error) (interface{}, error) {
787 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
788 | // This Catch function will be executed when the Promise is rejected
789 | fmt.Println("> catch 1")
790 |
791 | // 返回一个新的错误,将会被下一个 Catch 函数接收
792 | // Return a new error, which will be received by the next Catch function
793 | return nil, err
794 |
795 | }).Catch(func(err error) (interface{}, error) {
796 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
797 | // This Catch function will be executed when the previous Catch function returns an error
798 | fmt.Println("> catch 2")
799 |
800 | // 返回一个新的错误,将会被下一个 Catch 函数接收
801 | // Return a new error, which will be received by the next Catch function
802 | return nil, errors.New("rejected.200")
803 |
804 | }).Catch(func(err error) (interface{}, error) {
805 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
806 | // This Catch function will be executed when the previous Catch function returns an error
807 | fmt.Println("> catch 3")
808 |
809 | // 返回一个新的错误,将会被下一个 Catch 函数接收
810 | // Return a new error, which will be received by the next Catch function
811 | return nil, errors.New("rejected.300")
812 |
813 | }).Then(func(value interface{}) (interface{}, error) {
814 | // 当 Promise 被解决时,会执行这个 Then 函数
815 | // This Then function will be executed when the Promise is resolved
816 | fmt.Println("> then 1")
817 |
818 | // 返回一个新的值,将会被下一个 Then 函数接收
819 | // Return a new value, which will be received by the next Then function
820 | return fmt.Sprintf("Never be here!! recover value: %v", value), nil
821 |
822 | }, func(err error) (interface{}, error) {
823 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
824 | // This Catch function will be executed when the Promise is rejected
825 | fmt.Println("> catch 4")
826 |
827 | // 返回一个新的错误,将会被下一个 Catch 函数接收
828 | // Return a new error, which will be received by the next Catch function
829 | return nil, errors.New("Should be here.")
830 | })
831 |
832 | // 打印 Promise 被拒绝的原因
833 | // Print the reason the Promise was rejected
834 | fmt.Println("reason: ", result.GetReason())
835 |
836 | // 打印 Promise 的值,但是在这个例子中,Promise 会被拒绝,所以值会是 nil
837 | // Print the value of the Promise, but in this case, the Promise will be rejected, so the value will be nil
838 | fmt.Println("value: ", result.GetValue())
839 |
840 | }
841 | ```
842 |
843 | **执行结果**
844 |
845 | ```bash
846 | $ go run demo.go
847 | > catch 1
848 | > catch 2
849 | > catch 3
850 | > catch 4
851 | reason: Should be here.
852 | value:
853 | ```
854 |
855 | #### # 案例 10
856 |
857 | 创建一个 Promise 对象后,您可以使用 `reject` 函数触发一个错误。每个后续的 `catch()` 函数将处理前一个错误并返回一个新的错误。如果一个 `catch()` 函数成功从错误中恢复并返回一个正常值(`error` 设置为 `nil`),则所有后续的 `catch()` 函数将不会被执行。相反,`then()` 函数将返回这个值。
858 |
859 | **示例**
860 |
861 | ```go
862 | package main
863 |
864 | import (
865 | "errors"
866 | "fmt"
867 |
868 | vl "github.com/shengyanli1982/vowlink"
869 | )
870 |
871 | func main() {
872 |
873 | // 创建一个新的 Promise
874 | // Create a new Promise
875 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
876 | // 这个 Promise 会立即被拒绝,原因是 "rejected.100"
877 | // This Promise will be immediately rejected with the reason "rejected.100"
878 | reject(nil, fmt.Errorf("rejected.100"))
879 |
880 | }).Catch(func(err error) (interface{}, error) {
881 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
882 | // This Catch function will be executed when the Promise is rejected
883 | fmt.Println("> catch 1")
884 |
885 | // 返回一个新的错误,将会被下一个 Catch 函数接收
886 | // Return a new error, which will be received by the next Catch function
887 | return nil, err
888 |
889 | }).Catch(func(err error) (interface{}, error) {
890 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
891 | // This Catch function will be executed when the previous Catch function returns an error
892 | fmt.Println("> catch 2")
893 |
894 | // 返回一个新的值,将会被下一个 Then 函数接收
895 | // Return a new value, which will be received by the next Then function
896 | return "[error handled]", nil
897 |
898 | }).Catch(func(err error) (interface{}, error) {
899 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
900 | // This Catch function will be executed when the previous Catch function returns an error
901 | fmt.Println("> catch 3")
902 |
903 | // 返回一个新的错误,将会被下一个 Catch 函数接收
904 | // Return a new error, which will be received by the next Catch function
905 | return nil, errors.New("rejected.200")
906 |
907 | }).Then(func(value interface{}) (interface{}, error) {
908 | // 当 Promise 被解决时,会执行这个 Then 函数
909 | // This Then function will be executed when the Promise is resolved
910 | fmt.Println("> then 1")
911 |
912 | // 返回一个新的值,将会被下一个 Then 函数接收
913 | // Return a new value, which will be received by the next Then function
914 | return fmt.Sprintf("Should be here. recover value: %v", value), nil
915 |
916 | }, func(err error) (interface{}, error) {
917 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
918 | // This Catch function will be executed when the Promise is rejected
919 | fmt.Println("> catch 4")
920 |
921 | // 返回一个新的错误,将会被下一个 Catch 函数接收
922 | // Return a new error, which will be received by the next Catch function
923 | return nil, errors.New("Never be here!!")
924 |
925 | })
926 |
927 | // 输出 Promise 的拒绝原因,这里一定是 "nil"
928 | // Print the rejection reason of the Promise, it must be "nil" here
929 | fmt.Println("reason: ", result.GetReason())
930 |
931 | // 输出 Promise 的解决值,这里一定是 "Should be here."
932 | // Print the resolution value of the Promise, it must be "Should be here." here
933 | fmt.Println("value: ", result.GetValue())
934 |
935 | }
936 | ```
937 |
938 | **执行结果**
939 |
940 | ```bash
941 | $ go run demo.go
942 | > catch 1
943 | > catch 2
944 | > then 1
945 | reason:
946 | value: Should be here. recover value: [error handled]
947 | ```
948 |
949 | #### # 案例 11
950 |
951 | 在创建 Promise 对象后,使用 `resolve` 函数来处理正常的响应,但解决的值是一个错误。应该在 Promise 后使用 `then()` 函数来处理错误对象,并将结果存储为值。后续的 `catch()` 函数不会对此错误做出响应。
952 |
953 | **示例**
954 |
955 | ```go
956 | package main
957 |
958 | import (
959 | "errors"
960 | "fmt"
961 |
962 | vl "github.com/shengyanli1982/vowlink"
963 | )
964 |
965 | // 定义 main 函数
966 | // Define the main function
967 | func main() {
968 |
969 | // 创建一个新的 Promise
970 | // Create a new Promise
971 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
972 | // 这个 Promise 将继续执行,并将错误 "Something went wrong" 作为值传递给下一个 Promise
973 | // This Promise will continue to execute and pass the error "Something went wrong" as a value to the next Promise
974 | resolve(errors.New("Something went wrong"), nil)
975 |
976 | }).Then(func(data interface{}) (interface{}, error) {
977 | // 当 Promise 被解决时,会执行这个 Then 函数
978 | // This Then function will be executed when the Promise is resolved
979 | fmt.Println("> then 1")
980 |
981 | // 返回错误的字符串表示形式
982 | // Return the string representation of the error
983 | return data.(error).Error(), nil
984 |
985 | }, func(error) (interface{}, error) {
986 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
987 | // This Catch function will be executed when the Promise is rejected
988 | fmt.Println("> catch 1")
989 |
990 | // 返回一个新的错误 "Handled error"
991 | // Return a new error "Handled error"
992 | return nil, errors.New("Handled error")
993 |
994 | }).Catch(func(reason error) (interface{}, error) {
995 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
996 | // This Catch function will be executed when the Promise is rejected
997 | fmt.Println("> catch 2")
998 |
999 | // 返回一个字符串,表示恢复的值
1000 | // Return a string representing the recovered value
1001 | return fmt.Sprintf("Recovered value: %v", reason.Error()), nil
1002 |
1003 | })
1004 |
1005 | // 输出 Promise 的拒绝原因
1006 | // Print the rejection reason of the Promise
1007 | fmt.Println("reason: ", result.GetReason())
1008 |
1009 | // 输出 Promise 的解决值
1010 | // Print the resolution value of the Promise
1011 | fmt.Println("value: ", result.GetValue())
1012 |
1013 | }
1014 | ```
1015 |
1016 | **执行结果**
1017 |
1018 | ```bash
1019 | $ go run demo.go
1020 | > then 1
1021 | reason:
1022 | value: Something went wrong
1023 | ```
1024 |
1025 | #### # 案例 12
1026 |
1027 | 在创建 Promise 对象后,你可以使用 `reject` 函数来抛出异常。然而,`reject` 函数并不返回错误,而是返回一个值。只有 `then()` 函数处理 `reject` 传递的值,而后续的 `catch()` 函数会被跳过,不进行任何处理。
1028 |
1029 | **示例**
1030 |
1031 | ```go
1032 | package main
1033 |
1034 | import (
1035 | "errors"
1036 | "fmt"
1037 |
1038 | vl "github.com/shengyanli1982/vowlink"
1039 | )
1040 |
1041 | func main() {
1042 |
1043 | // 创建一个新的 Promise
1044 | // Create a new Promise
1045 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
1046 | // 这个 Promise 将继续执行,并将错误 "Something went wrong" 作为值传递给下一个 Promise
1047 | // This Promise will continue to execute and pass the error "Something went wrong" as a value to the next Promise
1048 | reject("Something went wrong", nil)
1049 |
1050 | }).Then(func(data interface{}) (interface{}, error) {
1051 | // 当 Promise 被解决时,会执行这个 Then 函数
1052 | // This Then function will be executed when the Promise is resolved
1053 | fmt.Println("> then 1")
1054 |
1055 | // 返回解决的值,将会被下一个 Then 函数接收
1056 | // Return the resolved value, which will be received by the next Then function
1057 | return data, nil
1058 |
1059 | }, func(error) (interface{}, error) {
1060 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
1061 | // This Catch function will be executed when the Promise is rejected
1062 | fmt.Println("> catch 1")
1063 |
1064 | // 返回一个新的错误 "Handled error"
1065 | // Return a new error "Handled error"
1066 | return nil, errors.New("Handled error")
1067 |
1068 | }).Catch(func(reason error) (interface{}, error) {
1069 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
1070 | // This Catch function will be executed when the Promise is rejected
1071 | fmt.Println("> catch 2")
1072 |
1073 | // 返回一个字符串,表示恢复的值
1074 | // Return a string representing the recovered value
1075 | return fmt.Sprintf("Recovered value: %v", reason.Error()), nil
1076 |
1077 | })
1078 |
1079 | // 输出 Promise 的拒绝原因
1080 | // Print the rejection reason of the Promise
1081 | fmt.Println("reason: ", result.GetReason())
1082 |
1083 | // 输出 Promise 的解决值
1084 | // Print the resolution value of the Promise
1085 | fmt.Println("value: ", result.GetValue())
1086 |
1087 | }
1088 | ```
1089 |
1090 | **执行结果**
1091 |
1092 | ```bash
1093 | $ go run demo.go
1094 | > then 1
1095 | reason:
1096 | value: Something went wrong
1097 | ```
1098 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | English | [中文](./README_CN.md)
2 |
3 |
4 |

5 |
6 |
7 | [](https://goreportcard.com/report/github.com/shengyanli1982/vowlink)
8 | [](https://github.com/shengyanli1982/vowlink/actions)
9 | [](https://pkg.go.dev/github.com/shengyanli1982/vowlink)
10 |
11 | ## Introduction
12 |
13 | Ever tried to explain quantum physics to your cat? Well, explaining `VowLink` might be just as challenging! Even after completing its first version, finding the perfect words to describe this elegant solution feels like trying to catch a laser pointer dot - always just out of reach.
14 |
15 | As a developer, I've frequently encountered the "callback pyramid of doom" - you know, that moment when your code starts looking like an ASCII art of the Egyptian pyramids. While ES6 Promises were a step in the right direction, I felt there was room for something even better in the Go ecosystem. Thus, `VowLink` was born - a Promise implementation that makes your Go code flow as smoothly as butter on a hot pancake.
16 |
17 | ## Advantages
18 |
19 | - Simple as pie (and just as delicious to use)
20 | - Zero dependencies (because sometimes less is more)
21 | - Full Promise API support including `then()`, `catch()`, `finally()`, `all()`, `race()`, `any()`, and `allSettled()` (it's like having the whole Promise family reunion!)
22 |
23 | ## Installation
24 |
25 | ```bash
26 | go get github.com/shengyanli1982/vowlink
27 | ```
28 |
29 | ## Quick Start
30 |
31 | Getting started with `VowLink` is easier than making instant noodles. Here's a taste of what it can do:
32 |
33 | **Example**
34 |
35 | ```go
36 | package main
37 |
38 | import (
39 | "fmt"
40 | vl "github.com/shengyanli1982/vowlink"
41 | )
42 |
43 | func main() {
44 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
45 | resolve("hello world", nil)
46 | }).Then(func(value interface{}) (interface{}, error) {
47 | return value.(string) + " vowlink", nil
48 | }, nil).Then(func(value interface{}) (interface{}, error) {
49 | return value.(string) + " !!", nil
50 | }, nil)
51 |
52 | fmt.Println(result.GetValue())
53 | }
54 | ```
55 |
56 | **Result**
57 |
58 | ```bash
59 | $ go run demo.go
60 | hello world vowlink !!
61 | ```
62 |
63 | See? That was smoother than a fresh jar of skippy!
64 |
65 | Instead of boring you with theoretical examples that put coffee to shame, let's dive into some real-world scenarios. These practical examples will show you how `VowLink` can make your code dance like nobody's watching.
66 |
67 | ### Core Rules
68 |
69 | > [!IMPORTANT]
70 | >
71 | > Before we jump in, here are the golden rules of `VowLink` - think of them as the "Ten Commandments" of Promise handling in Go.
72 |
73 | 1. All `Then`, `Catch`, and `Finally` methods can return errors. Like a game of hot potato, these errors will keep bouncing through the chain until someone handles them properly (returns nil).
74 | 2. The `resolve` and `reject` methods support both data and error returns, giving `NewPromise` the flexibility of a yoga master.
75 | 3. `GetValue` and `GetReason` are terminal methods - they're like the full stop at the end of a sentence. Once called, they don't return a Promise object.
76 | 4. While `VowLink` takes inspiration from JavaScript Promises, it's been tailored for Go like a bespoke suit.
77 | 5. Don't use goroutines inside `Then()`, `Catch()`, or `Finally()` methods. If you need async operations, wrap the entire Promise in a goroutine - it's like putting the whole party in a separate room.
78 |
79 | ### Study Cases
80 |
81 | There are various cases in our work, and I will show you some examples. You can find the code for each case in the `examples` directory. For example, Case 1 is located in `examples/case1`.
82 |
83 | #### # Case 1
84 |
85 | Just like using `if` and `else` in our code, we often want to perform certain actions if a condition is true, and different actions if the condition is false.
86 |
87 | **Example**
88 |
89 | ```go
90 | package main
91 |
92 | import (
93 | "fmt"
94 |
95 | vl "github.com/shengyanli1982/vowlink"
96 | )
97 |
98 | func main() {
99 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
100 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
101 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
102 | // 这个 promise 直接解析为 "hello world"
103 | // This promise is directly resolved to "hello world"
104 | resolve("hello world", nil)
105 | }).Then(func(value interface{}) (interface{}, error) {
106 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
107 | // In the Then method, we append " vowlink !!" to the resolved value
108 | return value.(string) + " vowlink !!", nil
109 | }, func(err error) (interface{}, error) {
110 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
111 | // If the promise is rejected, we return a new error message "rejected."
112 | return nil, fmt.Errorf("rejected.")
113 | })
114 |
115 | // 从 promise 中获取值并打印
116 | // Get the value from the promise and print it
117 | fmt.Println("Resolve:", result.GetValue())
118 |
119 | // 这是一个被拒绝的 promise
120 | // This is a rejected promise
121 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
122 | // 这个 promise 被拒绝,原因是 "error"
123 | // This promise is rejected with the reason "error"
124 | reject(nil, fmt.Errorf("error"))
125 | }).Then(func(value interface{}) (interface{}, error) {
126 | // 如果 promise 被解析,我们将解析的值加上 " vowlink"
127 | // If the promise is resolved, we append " vowlink" to the resolved value
128 | return value.(string) + " vowlink", nil
129 | }, func(err error) (interface{}, error) {
130 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
131 | // If the promise is rejected, we return a new error message "rejected."
132 | return nil, fmt.Errorf("rejected.")
133 | })
134 |
135 | // 从 promise 中获取拒绝的原因并打印
136 | // Get the reason for the rejection from the promise and print it
137 | fmt.Println("Rejected:", result.GetReason().Error())
138 | }
139 | ```
140 |
141 | **Result**
142 |
143 | ```bash
144 | $ go run demo.go
145 | Resolve: hello world vowlink !!
146 | Rejected: rejected.
147 | ```
148 |
149 | #### # Case 2
150 |
151 | I prefer using JavaScript-style code in Golang. I want to use `then()` to perform actions after the promise is resolved and `catch()` to handle rejected promises.
152 |
153 | **Example**
154 |
155 | ```go
156 | package main
157 |
158 | import (
159 | "fmt"
160 |
161 | vl "github.com/shengyanli1982/vowlink"
162 | )
163 |
164 | func main() {
165 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
166 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
167 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
168 | // 这个 promise 直接解析为 "hello world"
169 | // This promise is directly resolved to "hello world"
170 | resolve("hello world", nil)
171 | }).Then(func(value interface{}) (interface{}, error) {
172 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
173 | // In the Then method, we append " vowlink !!" to the resolved value
174 | return value.(string) + " vowlink !!", nil
175 | }, nil).Catch(func(err error) (interface{}, error) {
176 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
177 | // If the promise is rejected, we return a new error message "rejected."
178 | return nil, fmt.Errorf("rejected.")
179 | })
180 |
181 | // 从 promise 中获取值并打印
182 | // Get the value from the promise and print it
183 | fmt.Println("Resolve:", result.GetValue())
184 |
185 | // 这是一个被拒绝的 promise
186 | // This is a rejected promise
187 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
188 | // 这个 promise 被拒绝,原因是 "error"
189 | // This promise is rejected with the reason "error"
190 | reject(nil, fmt.Errorf("error"))
191 | }).Then(func(value interface{}) (interface{}, error) {
192 | // 如果 promise 被解析,我们将解析的值加上 " vowlink !!"
193 | // If the promise is resolved, we append " vowlink !!" to the resolved value
194 | return value.(string) + " vowlink !!", nil
195 | }, nil).Catch(func(err error) (interface{}, error) {
196 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
197 | // If the promise is rejected, we return a new error message "rejected."
198 | return nil, fmt.Errorf("rejected.")
199 | })
200 |
201 | // 从 promise 中获取拒绝的原因并打印
202 | // Get the reason for the rejection from the promise and print it
203 | fmt.Println("Rejected:", result.GetReason().Error())
204 | }
205 | ```
206 |
207 | **Result**
208 |
209 | ```bash
210 | $ go run demo.go
211 | Resolve: hello world vowlink !!
212 | Rejected: rejected.
213 | ```
214 |
215 | #### # Case 3
216 |
217 | I want to use `finally()` to do something after the promise is resolved or rejected.
218 |
219 | **Example**
220 |
221 | ```go
222 | package main
223 |
224 | import (
225 | "errors"
226 | "fmt"
227 |
228 | vl "github.com/shengyanli1982/vowlink"
229 | )
230 |
231 | func main() {
232 |
233 | // 输出 "========== finally 1 successfully ==========" 到控制台
234 | // Print "========== finally 1 successfully ==========" to the console
235 | fmt.Println("========== finally 1 successfully ==========")
236 |
237 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
238 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
239 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
240 | // 这个 promise 直接解析为 "hello world"
241 | // This promise is directly resolved to "hello world"
242 | resolve("hello world", nil)
243 | }).Then(func(value interface{}) (interface{}, error) {
244 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
245 | // In the Then method, we append " vowlink !!" to the resolved value
246 | return value.(string) + " vowlink !!", nil
247 | }, nil).Catch(func(err error) (interface{}, error) {
248 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
249 | // If the promise is rejected, we return a new error message "rejected."
250 | return nil, fmt.Errorf("rejected.")
251 | }).Finally(func() error {
252 | // 不论 promise 是被解析还是被拒绝,Finally 方法都会被调用,并打印 "finally 1"
253 | // Whether the promise is resolved or rejected, the Finally method will be called and print "finally 1"
254 | fmt.Println("finally 1")
255 |
256 | // 返回 nil 表示 Finally 方法执行成功
257 | // Return nil indicates that the Finally method was executed successfully
258 | return nil
259 | })
260 |
261 | // 使用 Printf 函数输出 "finally 1 is called. value: %v, error: %v\n" 到控制台
262 | // 使用 result.GetValue() 和 result.GetReason() 作为 Printf 函数的参数
263 | // Use the Printf function to output "finally 1 is called. value: %v, error: %v\n" to the console
264 | // Use result.GetValue() and result.GetReason() as the parameters of the Printf function
265 | fmt.Printf("finally 1 is called. value: %v, error: %v\n", result.GetValue(), result.GetReason())
266 |
267 | // 输出 "========== finally 1 error ==========" 到控制台
268 | // Print "========== finally 1 error ==========" to the console
269 | fmt.Println("========== finally 1 error ==========")
270 |
271 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
272 | // 这个 promise 直接解析为 "hello world"
273 | // This promise is directly resolved to "hello world"
274 | resolve("hello world", nil)
275 | }).Then(func(value interface{}) (interface{}, error) {
276 | // 在 Then 方法中,我们将解析的值加上 " vowlink !!"
277 | // In the Then method, we append " vowlink !!" to the resolved value
278 | return value.(string) + " vowlink !!", nil
279 | }, nil).Catch(func(err error) (interface{}, error) {
280 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
281 | // If the promise is rejected, we return a new error message "rejected."
282 | return nil, fmt.Errorf("rejected.")
283 | }).Finally(func() error {
284 | // Finally 函数会在 Promise 完成(无论解决还是拒绝)后被调用
285 | // The Finally function will be called after the Promise is settled (either resolved or rejected)
286 | fmt.Println("finally error: 1")
287 |
288 | // 返回一个新的错误 "error in finally 1"
289 | // Return a new error "error in finally 1"
290 | return errors.New("error in finally 1")
291 | }).Then(func(data interface{}) (interface{}, error) {
292 | // 当 Promise 被解决时,会执行这个 Then 函数
293 | // This Then function will be executed when the Promise is resolved
294 |
295 | // 返回解决的值,将会被下一个 Then 函数接收
296 | // Return the resolved value, which will be received by the next Then function
297 | return data.(string) + " vowlink", nil
298 | }, func(reason error) (interface{}, error) {
299 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
300 | // This Catch function will be executed when the Promise is rejected
301 |
302 | // 返回一个新的错误 "Handled error: " 加上原因的错误信息
303 | // Return a new error "Handled error: " plus the error message of the reason
304 | return nil, errors.New("Handled error: " + reason.Error())
305 | })
306 |
307 | // 使用 Printf 函数输出 "finally 1 error, but then is called. value: %v, error: %v\n" 到控制台
308 | // 使用 result.GetValue() 和 result.GetReason().Error() 作为 Printf 函数的参数
309 | // Use the Printf function to output "finally 1 error, but then is called. value: %v, error: %v\n" to the console
310 | // Use result.GetValue() and result.GetReason().Error() as the parameters of the Printf function
311 | fmt.Printf("finally 1 error, but then is called. value: %v, error: %v\n", result.GetValue(), result.GetReason().Error())
312 |
313 | // 输出 "========== finally 2 successfully ==========" 到控制台
314 | // Print "========== finally 2 successfully ==========" to the console
315 | fmt.Println("========== finally 2 successfully ==========")
316 |
317 | // 这是一个被拒绝的 promise
318 | // This is a rejected promise
319 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
320 | // 这个 promise 被拒绝,原因是 "error"
321 | // This promise is rejected with the reason "error"
322 | reject(nil, fmt.Errorf("error"))
323 | }).Then(func(value interface{}) (interface{}, error) {
324 | // 如果 promise 被解析,我们将解析的值加上 " vowlink !!"
325 | // If the promise is resolved, we append " vowlink !!" to the resolved value
326 | return value.(string) + " vowlink !!", nil
327 | }, nil).Catch(func(err error) (interface{}, error) {
328 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
329 | // If the promise is rejected, we return a new error message "rejected."
330 | return nil, fmt.Errorf("rejected.")
331 | }).Finally(func() error {
332 | // 不论 promise 是被解析还是被拒绝,Finally 方法都会被调用,并打印 "finally 2"
333 | // Whether the promise is resolved or rejected, the Finally method will be called and print "finally 2"
334 | fmt.Println("finally 2")
335 |
336 | // 返回 nil 表示 Finally 方法执行成功
337 | // Return nil indicates that the Finally method was executed successfully
338 | return nil
339 | })
340 |
341 | // 使用 Printf 函数输出 "finally 2 is called. value: %v, error: %v\n" 到控制台
342 | // 使用 result.GetValue() 和 result.GetReason() 作为 Printf 函数的参数
343 | // Use the Printf function to output "finally 2 is called. value: %v, error: %v\n" to the console
344 | // Use result.GetValue() and result.GetReason() as the parameters of the Printf function
345 | fmt.Printf("finally 2 is called. value: %v, error: %v\n", result.GetValue(), result.GetReason())
346 |
347 | // 输出 "========== finally 2 error ==========" 到控制台
348 | // Print "========== finally 2 error ==========" to the console
349 | fmt.Println("========== finally 2 error ==========")
350 |
351 | // 这是一个被拒绝的 promise,Finally 方法中返回了一个错误信息
352 | // This is a rejected promise, and an error message is returned in the Finally method
353 | result = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
354 | // 这个 promise 被拒绝,原因是 "error"
355 | // This promise is rejected with the reason "error"
356 | reject(nil, fmt.Errorf("error"))
357 | }).Then(func(value interface{}) (interface{}, error) {
358 | // 如果 promise 被解析,我们将解析的值加上 " vowlink !!"
359 | // If the promise is resolved, we append " vowlink !!" to the resolved value
360 | return value.(string) + " vowlink !!", nil
361 | }, nil).Catch(func(err error) (interface{}, error) {
362 | // 如果 promise 被拒绝,我们将返回一个新的错误信息 "rejected."
363 | // If the promise is rejected, we return a new error message "rejected."
364 | return nil, fmt.Errorf("rejected.")
365 | }).Finally(func() error {
366 | // Finally 函数会在 Promise 完成(无论解决还是拒绝)后被调用
367 | // The Finally function will be called after the Promise is settled (either resolved or rejected)
368 |
369 | // 输出 "finally error: 2" 到控制台
370 | // Print "finally error: 2" to the console
371 | fmt.Println("finally error: 2")
372 |
373 | // 返回一个新的错误 "error in finally 2"
374 | // Return a new error "error in finally 2"
375 | return errors.New("error in finally 2")
376 |
377 | }).Then(func(data interface{}) (interface{}, error) {
378 | // 当 Promise 被���决时,会执行这个 Then 函数
379 | // This Then function will be executed when the Promise is resolved
380 |
381 | // 返回解决的值,将会被下一个 Then 函数接收
382 | // Return the resolved value, which will be received by the next Then function
383 | return data.(string) + " vowlink", nil
384 | }, func(reason error) (interface{}, error) {
385 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
386 | // This Catch function will be executed when the Promise is rejected
387 |
388 | // 返回一个新的错误 "Handled error: " 加上原因的错误信息
389 | // Return a new error "Handled error: " plus the error message of the reason
390 | return nil, errors.New("Handled error: " + reason.Error())
391 | })
392 |
393 | // 使用 Printf 函数输出 "finally 2 error, but then is called. value: %v, error: %v\n" 到控制台
394 | // 使用 result.GetValue() 和 result.GetReason().Error() 作为 Printf 函数的参数
395 | // Use the Printf function to output "finally 2 error, but then is called. value: %v, error: %v\n" to the console
396 | // Use result.GetValue() and result.GetReason().Error() as the parameters of the Printf function
397 | fmt.Printf("finally 2 error, but then is called. value: %v, error: %v\n", result.GetValue(), result.GetReason().Error())
398 | }
399 | ```
400 |
401 | **Result**
402 |
403 | ```bash
404 | $ go run demo.go
405 | ========== finally 1 successfully ==========
406 | finally 1
407 | finally 1 is called. value: hello world vowlink !!, error:
408 | ========== finally 1 error ==========
409 | finally error: 1
410 | finally 1 error, but then is called. value: , error: Handled error: error in finally 1
411 | ========== finally 2 successfully ==========
412 | finally 2
413 | finally 2 is called. value: , error: rejected.
414 | ========== finally 2 error ==========
415 | finally error: 2
416 | finally 2 error, but then is called. value: , error: Handled error: error in finally 2
417 | ```
418 |
419 | #### # Case 4
420 |
421 | Yes, you can return a new promise using the `then()` method.
422 |
423 | **Example**
424 |
425 | ```go
426 | package main
427 |
428 | import (
429 | "fmt"
430 |
431 | vl "github.com/shengyanli1982/vowlink"
432 | )
433 |
434 | func main() {
435 | // vowlink 像一个链条,你可以在链条上添加更多的 then() 来在 promise 解析后做更多的事情。
436 | // vowlink is like a chain, you can add more then() to the chain to do more things after the promise is resolved.
437 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
438 | // 这个 promise 直接解析为 "hello world"
439 | // This promise is directly resolved to "hello world"
440 | resolve("hello world", nil)
441 | }).Then(func(value interface{}) (interface{}, error) {
442 | // 在 Then 方法中,我们创建一个新的 promise,将解析的值加上 " vowlink(NewPromise)"
443 | // In the Then method, we create a new promise, appending " vowlink(NewPromise)" to the resolved value
444 | return vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
445 | resolve(value.(string)+" vowlink(NewPromise)", nil)
446 | }), nil
447 | }, nil).Then(func(value interface{}) (interface{}, error) {
448 | // 在这个 Then 方法中,我们获取前一个 promise 的值,并加上 " !!"
449 | // In this Then method, we get the value from the previous promise and append " !!"
450 | return value.(*vl.Promise).GetValue().(string) + " !!", nil
451 | }, nil)
452 |
453 | // 从 promise 中获取值并打印
454 | // Get the value from the promise and print it
455 | fmt.Println(result.GetValue())
456 | }
457 | ```
458 |
459 | **Result**
460 |
461 | ```bash
462 | $ go run demo.go
463 | hello world vowlink(NewPromise) !!
464 | ```
465 |
466 | #### # Case 5
467 |
468 | To perform an action after all promises are resolved, you can use the `all()` method.
469 |
470 | **Example**
471 |
472 | ```go
473 | package main
474 |
475 | import (
476 | "fmt"
477 |
478 | vl "github.com/shengyanli1982/vowlink"
479 | )
480 |
481 | func main() {
482 | // 创建 3 个 promise
483 | // Create 3 promises
484 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
485 | // 第一个 promise 直接解析为 "Promise"
486 | // The first promise is directly resolved to "Promise"
487 | resolve("Promise", nil)
488 | }).Then(func(value interface{}) (interface{}, error) {
489 | // 在 Then 方法中,将解析的值加上 " 1"
490 | // In the Then method, append " 1" to the resolved value
491 | return value.(string) + " 1", nil
492 | }, nil)
493 |
494 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
495 | // 第二个 promise 直接解析为 "Promise"
496 | // The second promise is directly resolved to "Promise"
497 | resolve("Promise", nil)
498 | }).Then(func(value interface{}) (interface{}, error) {
499 | // 在 Then 方法中,将解析的值加上 " 2"
500 | // In the Then method, append " 2" to the resolved value
501 | return value.(string) + " 2", nil
502 | }, nil)
503 |
504 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
505 | // 第三个 promise 直接解析为 "Promise"
506 | // The third promise is directly resolved to "Promise"
507 | resolve("Promise", nil)
508 | }).Then(func(value interface{}) (interface{}, error) {
509 | // 在 Then 方法中,将解析的值加上 " 3"
510 | // In the Then method, append " 3" to the resolved value
511 | return value.(string) + " 3", nil
512 | }, nil)
513 |
514 | // All() 将等待所有的 promise 被解析,并返回一个带有所有值的 promise
515 | // All() will wait for all promises to be resolved, and return a promise with all the values
516 | result := vl.All(p1, p2, p3)
517 |
518 | // 从 promise 中获取所有的值并打印
519 | // Get all the values from the promise and print them
520 | for i, str := range result.GetValue().([]interface{}) {
521 | fmt.Println(">>", i, str.(string))
522 | }
523 | }
524 | ```
525 |
526 | **Result**
527 |
528 | ```bash
529 | $ go run demo.go
530 | >> 0 Promise 1
531 | >> 1 Promise 2
532 | >> 2 Promise 3
533 | ```
534 |
535 | #### # Case 6
536 |
537 | I want to use `race()` to perform an action once the first promise is resolved.
538 |
539 | **Example**
540 |
541 | ```go
542 | package main
543 |
544 | import (
545 | "fmt"
546 |
547 | vl "github.com/shengyanli1982/vowlink"
548 | )
549 |
550 | func main() {
551 | // 创建 3 个 promise
552 | // Create 3 promises
553 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
554 | // 第一个 promise 直接解析为 "Promise"
555 | // The first promise is directly resolved to "Promise"
556 | resolve("Promise", nil)
557 | }).Then(func(value interface{}) (interface{}, error) {
558 | // 在 Then 方法中,将解析的值加上 " 1"
559 | // In the Then method, append " 1" to the resolved value
560 | return value.(string) + " 1", nil
561 | }, nil)
562 |
563 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
564 | // 第二个 promise 直接解析为 "Promise"
565 | // The second promise is directly resolved to "Promise"
566 | resolve("Promise", nil)
567 | }).Then(func(value interface{}) (interface{}, error) {
568 | // 在 Then 方法中,将解析的值加上 " 2"
569 | // In the Then method, append " 2" to the resolved value
570 | return value.(string) + " 2", nil
571 | }, nil)
572 |
573 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
574 | // 第三个 promise 直接解析为 "Promise"
575 | // The third promise is directly resolved to "Promise"
576 | resolve("Promise", nil)
577 | }).Then(func(value interface{}) (interface{}, error) {
578 | // 在 Then 方法中,将解析的值加上 " 3"
579 | // In the Then method, append " 3" to the resolved value
580 | return value.(string) + " 3", nil
581 | }, nil)
582 |
583 | // Race() 将等待第一个 promise 被解析,并返回一个带有值的 promise
584 | // Race() will wait for the first promise to be resolved, and return a promise with the value
585 | result := vl.Race(p1, p2, p3)
586 |
587 | // 从 promise 中获取值并打印
588 | // Get the value from the promise and print it
589 | fmt.Println(">>", result.GetValue().(string))
590 | }
591 | ```
592 |
593 | **Result**
594 |
595 | ```bash
596 | $ go run demo.go
597 | >> Promise 1
598 | ```
599 |
600 | #### # Case 7
601 |
602 | I want to use `any()` to perform an action once the first promise is resolved. `any()` is similar to `race` in ES6. However, `any()` also captures any errors from all promises and returns an `AggregateError` if all promises are rejected.
603 |
604 | **Example**
605 |
606 | ```go
607 | package main
608 |
609 | import (
610 | "errors"
611 | "fmt"
612 |
613 | vl "github.com/shengyanli1982/vowlink"
614 | )
615 |
616 | func main() {
617 | // 创建 3 个 promise
618 | // Create 3 promises
619 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
620 | // 第一个 promise 直接解析为 "Promise"
621 | // The first promise is directly resolved to "Promise"
622 | resolve("Promise", nil)
623 | }).Then(func(value interface{}) (interface{}, error) {
624 | // 在 Then 方法中,将解析的值加上 " 1"
625 | // In the Then method, append " 1" to the resolved value
626 | return value.(string) + " 1", nil
627 | }, nil)
628 |
629 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
630 | // 第二个 promise 直接解析为 "Promise"
631 | // The second promise is directly resolved to "Promise"
632 | resolve("Promise", nil)
633 | }).Then(func(value interface{}) (interface{}, error) {
634 | // 在 Then 方法中,将解析的值加上 " 2"
635 | // In the Then method, append " 2" to the resolved value
636 | return value.(string) + " 2", nil
637 | }, nil)
638 |
639 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
640 | // 第三个 promise 直接解析为 "Promise"
641 | // The third promise is directly resolved to "Promise"
642 | resolve("Promise", nil)
643 | }).Then(func(value interface{}) (interface{}, error) {
644 | // 在 Then 方法中,将解析的值加上 " 3"
645 | // In the Then method, append " 3" to the resolved value
646 | return value.(string) + " 3", nil
647 | }, nil)
648 |
649 | // Any() 将等待第一个 promise 被解析,并返回一个带有值的 promise
650 | // Any() will wait for the first promise to be resolved, and return a promise with the value
651 | result := vl.Any(p1, p2, p3)
652 |
653 | // 从 promise 中获取值并打印
654 | // Get the value from the promise and print it
655 | fmt.Println(">>", result.GetValue().(string))
656 |
657 | // 创建 3 个 promise
658 | // Create 3 promises
659 | p1 = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
660 | // 第一个 promise 被拒绝,原因是 "Promise 1 rejected"
661 | // The first promise is rejected with the reason "Promise 1 rejected"
662 | reject(nil, errors.New("Promise 1 rejected"))
663 | })
664 |
665 | p2 = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
666 | // 第二个 promise 被拒绝,原因是 "Promise 2 rejected"
667 | // The second promise is rejected with the reason "Promise 2 rejected"
668 | reject(nil, errors.New("Promise 2 rejected"))
669 | })
670 |
671 | p3 = vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
672 | // 第三个 promise 被拒绝,原因是 "Promise 3 rejected"
673 | // The third promise is rejected with the reason "Promise 3 rejected"
674 | reject(nil, errors.New("Promise 3 rejected"))
675 | })
676 |
677 | // Any() 将等待所有的 promise 被拒绝,并返回一个带有原因 `AggregateError` 的 promise
678 | // Any() will wait for all promises to be rejected, and return a promise with the reason `AggregateError`
679 | result = vl.Any(p1, p2, p3)
680 |
681 | // 从 promise 中获取原因并打印
682 | // Get the reason from the promise and print it
683 | fmt.Println("!!", result.GetReason().Error())
684 | }
685 | ```
686 |
687 | **Result**
688 |
689 | ```bash
690 | $ go run demo.go
691 | >> Promise 1
692 | !! All promises were rejected: Promise 1 rejected, Promise 2 rejected, Promise 3 rejected
693 | ```
694 |
695 | #### # Case 8
696 |
697 | To perform an action after all promises are resolved or rejected, you can use the `allSettled()` method.
698 |
699 | **Example**
700 |
701 | ```go
702 | package main
703 |
704 | import (
705 | "errors"
706 | "fmt"
707 |
708 | vl "github.com/shengyanli1982/vowlink"
709 | )
710 |
711 | func main() {
712 | // 创建 3 个 promise
713 | // Create 3 promises
714 | p1 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
715 | // 第一个 promise 直接解析为 "Promise 1"
716 | // The first promise is directly resolved to "Promise 1"
717 | resolve("Promise 1", nil)
718 | })
719 |
720 | p2 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
721 | // 第二个 promise 被拒绝,原因是 "Promise 2 rejected"
722 | // The second promise is rejected with the reason "Promise 2 rejected"
723 | reject(nil, errors.New("Promise 2 rejected"))
724 | })
725 |
726 | p3 := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
727 | // 第三个 promise 直接解析为 "Promise 3"
728 | // The third promise is directly resolved to "Promise 3"
729 | resolve("Promise 3", nil)
730 | })
731 |
732 | // AllSettled() 将等待所有的 promise 被解析或拒绝,并返回一个带有值的 promise
733 | // AllSettled() will wait for all promises to be resolved or rejected, and return a promise with the value
734 | result := vl.AllSettled(p1, p2, p3)
735 |
736 | // 从 promise 中获取所有的结果
737 | // Get all the results from the promise
738 | for i, r := range result.GetValue().([]interface{}) {
739 | // 如果结果是一个错误,打印错误信息
740 | // If the result is an error, print the error message
741 | if v, ok := r.(error); ok {
742 | fmt.Println("!!", i, v.Error())
743 | } else {
744 | // 否则,打印结果值
745 | // Otherwise, print the result value
746 | fmt.Println(">>", i, r.(string))
747 | }
748 | }
749 | }
750 | ```
751 |
752 | **Result**
753 |
754 | ```bash
755 | $ go run demo.go
756 | >> 0 Promise 1
757 | !! 1 Promise 2 rejected
758 | >> 2 Promise 3
759 | ```
760 |
761 | #### # Case 9
762 |
763 | After creating a Promise object, you can use the `reject` function to trigger an error. Subsequent `catch()` functions will handle the previous error and return a new one, creating a chain of error calls.
764 |
765 | ```go
766 | package main
767 |
768 | import (
769 | "errors"
770 | "fmt"
771 |
772 | vl "github.com/shengyanli1982/vowlink"
773 | )
774 |
775 | func main() {
776 |
777 | // 创建一个新的 Promise
778 | // Create a new Promise
779 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
780 | // 这个 Promise 会立即被拒绝,原因是 "rejected.100"
781 | // This Promise will be immediately rejected with the reason "rejected.100"
782 | reject(nil, fmt.Errorf("rejected.100"))
783 |
784 | }).Catch(func(err error) (interface{}, error) {
785 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
786 | // This Catch function will be executed when the Promise is rejected
787 | fmt.Println("> catch 1")
788 |
789 | // 返回一个新的错误,将会被下一个 Catch 函数接收
790 | // Return a new error, which will be received by the next Catch function
791 | return nil, err
792 |
793 | }).Catch(func(err error) (interface{}, error) {
794 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
795 | // This Catch function will be executed when the previous Catch function returns an error
796 | fmt.Println("> catch 2")
797 |
798 | // 返回一个新的错误,将会被下一个 Catch 函数接收
799 | // Return a new error, which will be received by the next Catch function
800 | return nil, errors.New("rejected.200")
801 |
802 | }).Catch(func(err error) (interface{}, error) {
803 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
804 | // This Catch function will be executed when the previous Catch function returns an error
805 | fmt.Println("> catch 3")
806 |
807 | // 返回一个新的错误,将会被下一个 Catch 函数接收
808 | // Return a new error, which will be received by the next Catch function
809 | return nil, errors.New("rejected.300")
810 |
811 | }).Then(func(value interface{}) (interface{}, error) {
812 | // 当 Promise 被解决时,会执行这个 Then 函数
813 | // This Then function will be executed when the Promise is resolved
814 | fmt.Println("> then 1")
815 |
816 | // 返回一个新的值,将会被下一个 Then 函数接收
817 | // Return a new value, which will be received by the next Then function
818 | return fmt.Sprintf("Never be here!! recover value: %v", value), nil
819 |
820 | }, func(err error) (interface{}, error) {
821 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
822 | // This Catch function will be executed when the Promise is rejected
823 | fmt.Println("> catch 4")
824 |
825 | // 返回一个新的错误,将会被下一个 Catch 函数接收
826 | // Return a new error, which will be received by the next Catch function
827 | return nil, errors.New("Should be here.")
828 | })
829 |
830 | // 打印 Promise 被拒绝的原因
831 | // Print the reason the Promise was rejected
832 | fmt.Println("reason: ", result.GetReason())
833 |
834 | // 打印 Promise 的值,但是在这个例子中,Promise 会被拒绝,所以值会是 nil
835 | // Print the value of the Promise, but in this case, the Promise will be rejected, so the value will be nil
836 | fmt.Println("value: ", result.GetValue())
837 |
838 | }
839 | ```
840 |
841 | **Result**
842 |
843 | ```bash
844 | $ go run demo.go
845 | > catch 1
846 | > catch 2
847 | > catch 3
848 | > catch 4
849 | reason: Should be here.
850 | value:
851 | ```
852 |
853 | #### # Case 10
854 |
855 | After creating a Promise object, you can use the `reject` function to trigger an error. Each subsequent `catch()` function will handle the previous error and return a new one. If a `catch()` function successfully recovers from the error and returns a normal value (with `error` set to `nil`), all subsequent `catch()` functions will not be executed. Instead, the `then()` function will return this value.
856 |
857 | ```go
858 | package main
859 |
860 | import (
861 | "errors"
862 | "fmt"
863 |
864 | vl "github.com/shengyanli1982/vowlink"
865 | )
866 |
867 | func main() {
868 |
869 | // 创建一个新的 Promise
870 | // Create a new Promise
871 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
872 | // 这个 Promise 会立即被拒绝,原因是 "rejected.100"
873 | // This Promise will be immediately rejected with the reason "rejected.100"
874 | reject(nil, fmt.Errorf("rejected.100"))
875 |
876 | }).Catch(func(err error) (interface{}, error) {
877 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
878 | // This Catch function will be executed when the Promise is rejected
879 | fmt.Println("> catch 1")
880 |
881 | // 返回一个新的错误,将会被下一个 Catch 函数接收
882 | // Return a new error, which will be received by the next Catch function
883 | return nil, err
884 |
885 | }).Catch(func(err error) (interface{}, error) {
886 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
887 | // This Catch function will be executed when the previous Catch function returns an error
888 | fmt.Println("> catch 2")
889 |
890 | // 返回一个新的值,将会被下一个 Then 函数接收
891 | // Return a new value, which will be received by the next Then function
892 | return "[error handled]", nil
893 |
894 | }).Catch(func(err error) (interface{}, error) {
895 | // 当上一个 Catch 函数返回错误时,会执行这个 Catch 函数
896 | // This Catch function will be executed when the previous Catch function returns an error
897 | fmt.Println("> catch 3")
898 |
899 | // 返回一个新的错误,将会被下一个 Catch 函数接收
900 | // Return a new error, which will be received by the next Catch function
901 | return nil, errors.New("rejected.200")
902 |
903 | }).Then(func(value interface{}) (interface{}, error) {
904 | // 当 Promise 被解决时,会执行这个 Then 函数
905 | // This Then function will be executed when the Promise is resolved
906 | fmt.Println("> then 1")
907 |
908 | // 返回一个新的值,将会被下一个 Then 函数接收
909 | // Return a new value, which will be received by the next Then function
910 | return fmt.Sprintf("Should be here. recover value: %v", value), nil
911 |
912 | }, func(err error) (interface{}, error) {
913 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
914 | // This Catch function will be executed when the Promise is rejected
915 | fmt.Println("> catch 4")
916 |
917 | // 返回一个新的错误,将会被下一个 Catch 函数接收
918 | // Return a new error, which will be received by the next Catch function
919 | return nil, errors.New("Never be here!!")
920 |
921 | })
922 |
923 | // 输出 Promise 的拒绝原因,这里一定是 "nil"
924 | // Print the rejection reason of the Promise, it must be "nil" here
925 | fmt.Println("reason: ", result.GetReason())
926 |
927 | // 输出 Promise 的解决��,这里一定是 "Should be here."
928 | // Print the resolution value of the Promise, it must be "Should be here." here
929 | fmt.Println("value: ", result.GetValue())
930 |
931 | }
932 | ```
933 |
934 | **Result**
935 |
936 | ```bash
937 | $ go run demo.go
938 | > catch 1
939 | > catch 2
940 | > then 1
941 | reason:
942 | value: Should be here. recover value: [error handled]
943 | ```
944 |
945 | #### # Case 11
946 |
947 | After creating a Promise object, the `resolve` function is used to handle the normal response, but the resolved value is an error. The `then()` function should be used after the Promise to handle the error object and store the result as a value. Subsequent `catch()` functions do not respond to this error.
948 |
949 | ```go
950 | package main
951 |
952 | import (
953 | "errors"
954 | "fmt"
955 |
956 | vl "github.com/shengyanli1982/vowlink"
957 | )
958 |
959 | // 定义 main 函数
960 | // Define the main function
961 | func main() {
962 |
963 | // 创建一个新的 Promise
964 | // Create a new Promise
965 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
966 | // 这个 Promise 将继续执行,并将错误 "Something went wrong" 作为值传递给下一个 Promise
967 | // This Promise will continue to execute and pass the error "Something went wrong" as a value to the next Promise
968 | resolve(errors.New("Something went wrong"), nil)
969 |
970 | }).Then(func(data interface{}) (interface{}, error) {
971 | // 当 Promise 被解决时,会执行这个 Then 函数
972 | // This Then function will be executed when the Promise is resolved
973 | fmt.Println("> then 1")
974 |
975 | // 返回错误的字符串表示形式
976 | // Return the string representation of the error
977 | return data.(error).Error(), nil
978 |
979 | }, func(error) (interface{}, error) {
980 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
981 | // This Catch function will be executed when the Promise is rejected
982 | fmt.Println("> catch 1")
983 |
984 | // 返回一个新的错误 "Handled error"
985 | // Return a new error "Handled error"
986 | return nil, errors.New("Handled error")
987 |
988 | }).Catch(func(reason error) (interface{}, error) {
989 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
990 | // This Catch function will be executed when the Promise is rejected
991 | fmt.Println("> catch 2")
992 |
993 | // 返回一个字符串,表示恢复的值
994 | // Return a string representing the recovered value
995 | return fmt.Sprintf("Recovered value: %v", reason.Error()), nil
996 |
997 | })
998 |
999 | // 输出 Promise 的拒绝���因
1000 | // Print the rejection reason of the Promise
1001 | fmt.Println("reason: ", result.GetReason())
1002 |
1003 | // 输出 Promise 的解决值
1004 | // Print the resolution value of the Promise
1005 | fmt.Println("value: ", result.GetValue())
1006 |
1007 | }
1008 | ```
1009 |
1010 | **Result**
1011 |
1012 | ```bash
1013 | $ go run demo.go
1014 | > then 1
1015 | reason:
1016 | value: Something went wrong
1017 | ```
1018 |
1019 | #### # Case 12
1020 |
1021 | After creating a Promise object, you can use the `reject` function to raise an exception. However, the `reject` function does not return an error, but instead returns a value. Only the `then()` function handles the value passed by `reject`, while subsequent `catch()` functions are skipped without any processing.
1022 |
1023 | ```go
1024 | package main
1025 |
1026 | import (
1027 | "errors"
1028 | "fmt"
1029 |
1030 | vl "github.com/shengyanli1982/vowlink"
1031 | )
1032 |
1033 | func main() {
1034 |
1035 | // 创建一个新的 Promise
1036 | // Create a new Promise
1037 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
1038 | // 这个 Promise 将继续执行,并将错误 "Something went wrong" 作为值传递给下一个 Promise
1039 | // This Promise will continue to execute and pass the error "Something went wrong" as a value to the next Promise
1040 | reject("Something went wrong", nil)
1041 |
1042 | }).Then(func(data interface{}) (interface{}, error) {
1043 | // 当 Promise 被解决时,会执行这个 Then 函数
1044 | // This Then function will be executed when the Promise is resolved
1045 | fmt.Println("> then 1")
1046 |
1047 | // 返回解决的值,将会被下一个 Then 函数接收
1048 | // Return the resolved value, which will be received by the next Then function
1049 | return data, nil
1050 |
1051 | }, func(error) (interface{}, error) {
1052 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
1053 | // This Catch function will be executed when the Promise is rejected
1054 | fmt.Println("> catch 1")
1055 |
1056 | // 返回一个新的错误 "Handled error"
1057 | // Return a new error "Handled error"
1058 | return nil, errors.New("Handled error")
1059 |
1060 | }).Catch(func(reason error) (interface{}, error) {
1061 | // 当 Promise 被拒绝时,会执行这个 Catch 函数
1062 | // This Catch function will be executed when the Promise is rejected
1063 | fmt.Println("> catch 2")
1064 |
1065 | // 返回一个字符串,表示恢复的值
1066 | // Return a string representing the recovered value
1067 | return fmt.Sprintf("Recovered value: %v", reason.Error()), nil
1068 |
1069 | })
1070 |
1071 | // 输出 Promise 的拒绝原因
1072 | // Print the rejection reason of the Promise
1073 | fmt.Println("reason: ", result.GetReason())
1074 |
1075 | // 输出 Promise 的解决值
1076 | // Print the resolution value of the Promise
1077 | fmt.Println("value: ", result.GetValue())
1078 |
1079 | }
1080 | ```
1081 |
1082 | **Result**
1083 |
1084 | ```bash
1085 | $ go run demo.go
1086 | > then 1
1087 | reason:
1088 | value: Something went wrong
1089 | ```
1090 |
1091 | #### # Case 13
1092 |
1093 | Here's how to properly handle asynchronous operations with VowLink:
1094 |
1095 | > [!IMPORTANT]
1096 | >
1097 | > Do not use goroutines (e.g., `go func()`) inside `Then()`, `Catch()`, or `Finally()` methods. If you need asynchronous execution, wrap the entire Promise as a goroutine instead.
1098 |
1099 | ```go
1100 | package main
1101 |
1102 | import (
1103 | "fmt"
1104 | "time"
1105 |
1106 | vl "github.com/shengyanli1982/vowlink"
1107 | )
1108 |
1109 | func main() {
1110 | // Create a channel to wait for the async operation
1111 | done := make(chan struct{})
1112 |
1113 | // Launch the async operation
1114 | go func() {
1115 | result := vl.NewPromise(func(resolve func(interface{}, error), reject func(interface{}, error)) {
1116 | // Simulate some async work
1117 | time.Sleep(1 * time.Second)
1118 | resolve("Async operation completed", nil)
1119 | }).Then(func(value interface{}) (interface{}, error) {
1120 | fmt.Println("> Processing async result")
1121 | return value.(string) + "!", nil
1122 | }, nil)
1123 |
1124 | fmt.Println("Final result:", result.GetValue())
1125 | close(done)
1126 | }()
1127 |
1128 | // Wait for the async operation to complete
1129 | <-done
1130 | fmt.Println("Main function completed")
1131 | }
1132 | ```
1133 |
1134 | **Result**
1135 |
1136 | ```bash
1137 | $ go run demo.go
1138 | > Processing async result
1139 | Final result: Async operation completed!
1140 | Main function completed
1141 | ```
1142 |
--------------------------------------------------------------------------------