├── 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 | logo 5 |
6 | 7 | [![Go Report Card](https://goreportcard.com/badge/github.com/shengyanli1982/vowlink)](https://goreportcard.com/report/github.com/shengyanli1982/vowlink) 8 | [![Build Status](https://github.com/shengyanli1982/vowlink/actions/workflows/test.yaml/badge.svg)](https://github.com/shengyanli1982/vowlink/actions) 9 | [![Go Reference](https://pkg.go.dev/badge/github.com/shengyanli1982/vowlink.svg)](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 | logo 5 |
6 | 7 | [![Go Report Card](https://goreportcard.com/badge/github.com/shengyanli1982/vowlink)](https://goreportcard.com/report/github.com/shengyanli1982/vowlink) 8 | [![Build Status](https://github.com/shengyanli1982/vowlink/actions/workflows/test.yaml/badge.svg)](https://github.com/shengyanli1982/vowlink/actions) 9 | [![Go Reference](https://pkg.go.dev/badge/github.com/shengyanli1982/vowlink.svg)](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 | --------------------------------------------------------------------------------