├── .editorconfig ├── .vscode └── launch.json ├── LICENSE ├── README.md ├── debug ├── example └── example1.go ├── go.mod └── promise.go /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{go}] 2 | indent_style = space 3 | indent_size = 4 4 | end_of_line = lf 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | max_line_length = 100 8 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch", 9 | "type": "go", 10 | "request": "launch", 11 | "mode": "auto", 12 | "program": "${workspaceFolder}/main.go", 13 | "env": {}, 14 | "args": [] 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Igor Halfeld 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Go Promise 🐰 2 | 3 | Manage async flow as a javascript person 4 | 5 | ### How to use 6 | 7 | ```go 8 | package main 9 | 10 | import ( 11 | "errors" 12 | "fmt" 13 | "net/http" 14 | 15 | "github.com/igorhalfeld/go-promise" 16 | ) 17 | 18 | func main() { 19 | p := promise.New(func(resolve func(interface{}), reject func(error)) { 20 | resp, err := http.Get("http://gobyexample.com") 21 | if err != nil { 22 | panic(err) 23 | } 24 | defer resp.Body.Close() 25 | 26 | if resp.StatusCode == 200 { 27 | resolve(resp.Status) 28 | } else { 29 | reject(errors.New("ERRR")) 30 | } 31 | }) 32 | 33 | p.Then(func(value interface{}) { 34 | fmt.Println("Success", value) 35 | }).Catch(func(err error) { 36 | fmt.Println("Error", err) 37 | }) 38 | 39 | p.Wait() 40 | } 41 | 42 | ``` 43 | 44 | ### Contributors 45 | 46 | ![brenin](https://avatars3.githubusercontent.com/u/16777941?s=100&v=4) | ![João Pedro](https://avatars0.githubusercontent.com/u/4886125?s=100&v=4) 47 | ------------------------------------------------------------------------|------------------------------------------------------------------------ 48 | [Breno Andrade](https://github.com/BrenoAndrade) | [João Pedro](https://github.com/joaopmgd) -------------------------------------------------------------------------------- /debug: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgorHalfeld/go-promise/6321ee9e7b4c276e028049403a82e79dfcb136cb/debug -------------------------------------------------------------------------------- /example/example1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "net/http" 7 | 8 | "github.com/igorhalfeld/go-promise" 9 | ) 10 | 11 | func main() { 12 | p := promise.New(func(resolve func(interface{}), reject func(error)) { 13 | resp, err := http.Get("http://gobyexample.com") 14 | if err != nil { 15 | panic(err) 16 | } 17 | defer resp.Body.Close() 18 | 19 | if resp.StatusCode == 200 { 20 | resolve(resp.Status) 21 | } else { 22 | reject(errors.New("ERRR")) 23 | } 24 | }) 25 | 26 | p.Then(func(value interface{}) { 27 | fmt.Println("Success", value) 28 | }).Catch(func(err error) { 29 | fmt.Println("Error", err) 30 | }) 31 | 32 | p.Wait() 33 | } 34 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/igorhalfeld/go-promise 2 | 3 | go 1.12 4 | -------------------------------------------------------------------------------- /promise.go: -------------------------------------------------------------------------------- 1 | package promise 2 | 3 | // Promise represents a promise struct 4 | type Promise struct { 5 | resolve chan interface{} 6 | reject chan error 7 | done chan bool 8 | } 9 | 10 | // New represents a new instance of Promise struct 11 | func New(fn func(func(interface{}), func(error))) *Promise { 12 | promise := &Promise{ 13 | resolve: make(chan interface{}, 1), 14 | reject: make(chan error, 1), 15 | done: make(chan bool, 1), 16 | } 17 | go fn(promise.resolveFn, promise.rejectFn) 18 | return promise 19 | } 20 | 21 | // Then represents a next chain of success flow 22 | func (p *Promise) Then(success func(interface{})) *Promise { 23 | go func() { 24 | if result, ok := <-p.resolve; ok { 25 | p.done <- ok 26 | success(result) 27 | close(p.reject) 28 | } 29 | }() 30 | return p 31 | } 32 | 33 | // Catch represents a next chain of failure flow 34 | func (p *Promise) Catch(failure func(error)) *Promise { 35 | go func() { 36 | if result, ok := <-p.reject; ok { 37 | p.done <- ok 38 | failure(result) 39 | close(p.resolve) 40 | } 41 | }() 42 | return p 43 | } 44 | 45 | func (p *Promise) Wait() { 46 | <-p.done 47 | } 48 | 49 | func (p *Promise) resolveFn(i interface{}) { 50 | p.resolve <- i 51 | } 52 | 53 | func (p *Promise) rejectFn(e error) { 54 | p.reject <- e 55 | } 56 | --------------------------------------------------------------------------------