promise

package module
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 2, 2021 License: Apache-2.0 Imports: 3 Imported by: 0

README

Promise PkgGoDev Go Report Card GoCoverIO Tests

Fast, lightweight, and lock-free promises for Go... the Go way

Features

  • Fast and low memory overhead implementation
  • Lock-free implementation
  • Extensible implementation that can be used to provide typed promises
  • Automatic panic recovering
  • An API that focuses on Go's idioms, like:
    • Multi return parameters
    • Error being a value
    • The convention of returning errors as the last return parameter
    • The existence of panics and their difference from errors.

Overview

What's a Promise ?

A Promise represents some asynchronous work. It offers ways to get the eventual result of that asynchronous work.
Read more on its Wiki page.

Why in Go ?

Waiting for a goroutine, or returning result from a goroutine, specially with multi return parameters, can get tedious, as it usually requires using more than one variable(a channel with a struct type whose fields correspond to the return parameters, or a sync.WaitGroup with some variables).

But using a promise, it's now possible to wait for the corresponding goroutine to finish and/or access the returned result from it, along with other features, like knowing the status of that goroutine, building computation pipelines, and recovering from panics.

Installation

go get github.com/asmsh/promise

Note: some breaking changes maybe present between each minor version, until the release of v1.0.0, so always check the changelog before updating.

Prerequisites

Go 1.13+

Usage

Basic Usage:
  • If you want to return some values from a goroutine:
p := promise.GoRes(func () promise.Res {
	/* do some work, asynchronously */
	return promise.Res{"go", "golang"} // return any values(as elements)
})
  • If you don't want to return any values:
p := promise.Go(func () {
	/* do some work, asynchronously */
})

Then use any of p's methods to wait for it, access its result, or create a pipeline.

Examples

  • The simplest use case, is to use it as a sync.WaitGroup with only one task:
package main

import "github.com/asmsh/promise"

func main() {
	p := promise.Go(func() {
		/* do some work, asynchronously */
	})

	/* do some other work */

	p.Wait() // wait for the async work to finish

	/* do some other work */
}

The following code is equivalent to the previous, but using only the standard library:

package main

import "sync"

func main() {
	wg := &sync.WaitGroup{}
	wg.Add(1)
	go func(wg *sync.WaitGroup) {
		/* do some work, asynchronously */
		wg.Done()
	}(wg)

	/* do some other work */

	wg.Wait() // wait for the async work to finish

	/* do some other work */
}
  • A typical use case, is to use it to return some result from a goroutine:
package main

import (
	"net/http"

	"github.com/asmsh/promise"
)

func main() {
	p := promise.GoRes(func() promise.Res {
		resp, err := http.Get("https://golang.org/")
		return promise.Res{resp, err}
	}).Then(func(res promise.Res, ok bool) promise.Res {
		// uncomment the following and do something with resp..
		//resp := res[0].(*http.Response)
		return nil
	}).Catch(func(err error, res promise.Res, ok bool) promise.Res {
		// handle the error..
		return nil
	})

	/* do some other work */

	p.Wait() // wait for all the work to finish

	/* do some other work */
}
  • It can be embedded or extended, to provide typed promises, like the asyncHttp, or the ctxProm examples.

  • It provides JavaScript-like Resolver constructor, which can be used like in this example.

Documentation

Overview

Package promise provides fast, lightweight, and lock-free promise implementations.

Besides speed and low memory overhead, it focuses on Go's idioms, like multi return parameters, error being a value, the convention of returning errors as the last return parameter, and the existence of panics and their difference from errors.

A Promise provides an easy way for returning results from a goroutine, and/or waiting for it to finish, plus other features.

States and Fates:-

A Promise has four states, and it can be in only one of them, at any time:

* Pending: the computation that corresponds to this Promise has not finished.

* Fulfilled: the computation that corresponds to this Promise has finished and returned a Res value with no error or with a nil error at the end.

* Rejected: the computation that corresponds to this Promise has finished and returned a Res value with a non-nil error at the end.

* Panicked: the computation that corresponds to this Promise has caused a panic.

A Promise has three fates, and it can be in only one of them, at any time:

* Unresolved: the computation that corresponds to this Promise is still working, and the final state of the Promise is still unknown.

* Resolved: the state of the Promise is now known, and final.

* Handled: the result of the Promise has been passed to some call of its methods.

General Notes:-

* Once the Promise's fate is Resolved, its result value will not change.

* A Promise whose fate is Unresolved, its state must be Pending.

* A Promise whose fate is Resolved, and its state is Pending, its fate will never be Handled.

* For a Promise's fate to be Handled, its fate must first be Resolved.

Implementations:-

* The module provides one Promise implementation, GoPromise(the default).

* The GoPromise's 'ok' callback parameter will always be true(except in a Finally callback on a panicked promise).

* The GoPromise's 'ok' return parameter(for GetRes) will always be true( except on a panicked promise).

Callback Notes:-

* The Res value returned from the callback must not be modified after return.

* If the callback called runtime.Goexit, the returned promise will be fulfilled to 'nil'.

* The underlying implementation of the returned Promise is always the default implementation(GoPromise), unless stated otherwise in the callback or the corresponding constructor docs.

* If the callback returned a non-nil error value as the last element in the returned Res value, the returned Promise will be a 'rejected' promise, and all subsequent promises in any promise chain derived from it, until the error is caught on each of these chains(by a Catch call).

* If the promise is running in the safe mode(the default), the returned Promise is a rejected promise, and the error is not caught(by a Catch call) before the end of that promise's chain, or the promise result is not read(by a GetRes call), a panic will happen with an error value of type *UnCaughtErr, which has that uncaught error 'wrapped' inside it.

* If the callback caused a panic, the resulting Promise will be a 'panicked' promise, and all subsequent promises in any promise chain derived from it, until recovering from the panic on each of these chains(by a Recover call).

* If the promise is running in the safe mode(the default), the returned Promise is a panicked promise, and it's not recovered(by a Recover call) before the end of the promise's chain, or before calling Finally, it will re-panic(with the same value passed to the original 'panic' call).

Modes:-

* The module provides two modes for promise creation, 'Safe', and 'NonSafe'.

* In the 'NonSafe' version, a 'rejected' or 'panicked' promise(resolved to the 'rejected' state or the 'panicked' state, respectively) will not panic if it reached the end of its promise chain without being handled( by a 'Catch' call or 'GetRes' call, in case of a 'rejected' promise, or a 'Recover' call, in case of 'panicked' promise). But in the 'Safe' version a panic will happen in either of these cases.

* The 'NonSafe' version is accessible from the NonSafeAPI variable.

* The 'Safe' version is the default, and is accessible from any function in the module.

Index

Constants

This section is empty.

Variables

View Source
var NonSafeAPI nonSafeCalls

NonSafeAPI exposes the 'NonSafe' version of the API of this module, as the 'Safe' version is the default and already accessible directly from this module.

All promises created through this will be 'NonSafe', and all promises that are derived from them too.

In the 'NonSafe' version, a 'rejected' or 'panicked' promise(resolved to the 'rejected' state or the 'panicked' state, respectively) will not panic if it reached the end of its promise chain without being handled( by a 'Catch' call or 'GetRes' call, in case of a 'rejected' promise, or a 'Recover' call, in case of 'panicked' promise). But in the 'Safe' version a panic will happen in either of these cases.

It should be used with care, as errors and panics might be returned or occurred and go unnoticed.

It is an extension variable that's sole purpose is to organize the API of the module, and encourage the use of the 'Safe' version of API.

Functions

func WaitAll

func WaitAll(proms ...Promise) (waited bool)

WaitAll waits all the provided promises to resolve then return true, or returns false if no promises are provided.

Types

type GoPromise

type GoPromise struct {
	// contains filtered or unexported fields
}

GoPromise is the default implementation of the Promise interface

The zero value will block forever on any calls.

func Delay added in v0.3.0

func Delay(res Res, d time.Duration, onSucceed, onFail bool) *GoPromise

Delay returns a GoPromise that's resolved to the passed Res value, res, after waiting for at least duration d, accordingly.

The returned promise is resolved to rejected, or fulfilled, depending on whether the last element in res is, respectively, a non-nil error value, or any other value.

If the promise is about to be fulfilled, resolving the promise will be delayed, only if onSucceed = true.

If the promise is about to be rejected, resolving the promise will be delayed, only if onFail = true.

The provided res value shouldn't be modified after this call.

If the returned promise is rejected, and the error is not caught(by a Catch call) before the end of the promise's chain, or the promise result is not read(by a GetRes call), a panic will happen with an error value of type *UnCaughtErr, which has that uncaught error 'wrapped' inside it.

func Fulfill

func Fulfill(vals ...interface{}) *GoPromise

Fulfill returns a GoPromise that's fulfilled, synchronously, and whose result is a Res value that contains the passed values, vals(if present).

The provided vals, if passed from a slice/array, the slice/array shouldn't be modified after this call.

func Go

func Go(fun func()) *GoPromise

Go runs the provided function, fun, in a separate goroutine, and returns a GoPromise whose result is a nil Res value.

The returned promise will be resolved to panicked, or fulfilled, depending on whether fun caused a panic, or returned normally, respectively.

If the callback called runtime.Goexit, the returned promise will be fulfilled to 'nil'.

If the returned promise is a panicked promise, and it's not recovered(by a Recover call) before the end of the promise's chain, or before calling Finally, it will re-panic(with the same value passed to the original 'panic' call).

It will panic if a nil function is passed.

func GoRes

func GoRes(fun func() Res) *GoPromise

GoRes runs the provided function, fun, in a separate goroutine, and returns a GoPromise whose result will be the Res value returned from fun.

The returned promise will be resolved to panicked, rejected, or fulfilled, depending on whether fun caused a panic, fun returned a non-nil error as the last element in the returned Res value, or fun returned a Res value which doesn't has a non-nil error as its last element, respectively.

If the callback called runtime.Goexit, the returned promise will be fulfilled to 'nil'.

If the returned promise is rejected, and the error is not caught(by a Catch call) before the end of the promise's chain, or the promise result is not read(by a GetRes call), a panic will happen with an error value of type *UnCaughtErr, which has that uncaught error 'wrapped' inside it.

If the returned promise is a panicked promise, and it's not recovered(by a Recover call) before the end of the promise's chain, or before calling Finally, it will re-panic(with the same value passed to the original 'panic' call).

It will panic if a nil function is passed.

func New

func New(resChan chan Res) *GoPromise

New returns a GoPromise that's created using the provided resChan.

The resChan must be a bi-directional chan(buffered or unbuffered), which is used from the caller(creator) side to do only one of the following, either send a Res value on it for one time, or just close it.

When a Res value is sent on it, the returned promise will be resolved(and the resChan is closed) to either rejected, or fulfilled, depending on whether the last element in that sent Res value is a non-nil error, or not, respectively. When the resChan is closed, the returned promise will be fulfilled, and its result will be a nil Res value.

If the resChan is not usd as described above, a panic will happen when it's used, either on the caller side, or here, internally.

If the returned promise is rejected, and the error is not caught(by a Catch call) before the end of the promise's chain, or the promise result is not read(by a GetRes call), a panic will happen with an error value of type *UnCaughtErr, which has that uncaught error 'wrapped' inside it.

func Panic

func Panic(v interface{}) *GoPromise

Panic returns a GoPromise that's resolved to panicked, synchronously, and whose result is the passed value, v.

The passed value, v, is only accessible from a Recover callback.

All subsequent promises in any promise chain derived from the returned promise needs to call Recover, before the end of each promise's chain, otherwise all these promise will re-panic(with the passed value, v).

func Reject

func Reject(err error, vals ...interface{}) *GoPromise

Reject returns a GoPromise that's rejected, synchronously, and whose result is a Res value that contains, both, the passed values, vals(if present), and the provided error, err(after vals, at the end), only if err is a non-nil error value.

If err is a nil error value, it returns a GoPromise that's fulfilled, synchronously, and whose result is a Res value that contains vals.

The provided vals, if passed from a slice/array, the slice/array shouldn't be modified after this call.

If the returned promise is rejected, it will not panic with an *UnCaughtErr error, but all subsequent promises in any promise chain derived from it will, until the error is caught on each of these chains(by a Catch call), or the promise result is read(by a GetRes call).

func Resolver

func Resolver(resolverCb func(fulfill func(vals ...interface{}), reject func(err error, vals ...interface{}))) *GoPromise

Resolver provides a JavaScript-like promise creation. It runs the provided resolverCb function in a separate goroutine, and returns a new GoPromise, which will be resolved using the functions passed to the resolverCb.

The returned promise will be fulfilled when the fulfill function is called, for the first time, and before the reject function, then the promise's result will be a Res value that contains the passed values, vals. Or, when calling the reject function, but with a nil error, and in that case the promise's result will be a Res value that contains the passed values, vals, and a nil, after them at the end.

The returned promise will be rejected when the reject function is called with a non nil error, for the first time, and before the fulfill function, then the promise's result will be a Res value that contains, both, the passed values, vals(if present), and the provided err(after vals, always at the end).

The returned promise will be panicked when the resolverCb causes a panic, before any calls to fulfill or reject is made.

If the callback called runtime.Goexit, before any calls to fulfill or reject is made, the returned promise will be fulfilled to 'nil'.

If the resolverCb causes a panic after calling fulfill or reject, the panic will not be recovered by the promise.

The fulfill and reject functions should not be called asynchronously, or more specifically, they should be called and returned before the resolverCb return.

The provided vals, if passed from a slice/array, the slice/array shouldn't be modified after this call.

If the returned promise is rejected, and the error is not caught(by a Catch call) before the end of the promise's chain, or the promise result is not read(by a GetRes call), a panic will happen with an error value of type *UnCaughtErr, which has that uncaught error 'wrapped' inside it.

If the returned promise is a panicked promise, and it's not recovered(by a Recover call) before the end of the promise's chain, or before calling Finally, it will re-panic(with the same value passed to the original 'panic' call).

It will panic if a nil function is passed.

func Wrap

func Wrap(res Res) *GoPromise

Wrap returns a GoPromise that's resolved, synchronously, to the provided Res value, res.

The returned promise is resolved to rejected, or fulfilled, depending on whether the last element in res is, respectively, a non-nil error value, or any other value.

The provided res value shouldn't be modified after this call.

If the returned promise is rejected, it will not panic with an *UnCaughtErr error, but all subsequent promises in any promise chain derived from it will, until the error is caught on each of these chains(by a Catch call), or the promise result is read(by a GetRes call).

func (*GoPromise) Catch

func (p *GoPromise) Catch(catchCb func(err error, res Res, ok bool) Res) Promise

Catch waits the promise to be resolved, and calls the catchCb function, if the promise is resolved to rejected.

It returns a GoPromise value whose result will be the Res value returned from the catchCb.

The Res value returned from the callback must not be modified after return.

The catchCb is passed with three arguments, the error that caused this promise to be rejected, err, this promise's result, res(including the error at the end), and a boolean, ok, which will always be true.

The result is passed here with the error, because, in Go, errors are just values, so returning them is not always considered an unwanted behaviour(example: io.EOF error), so some logic may depend on both.

Note that if the catchCb returned the res as-is, the returned promise will be rejected also(because there's a non-nil error at its end).

It will panic if a nil callback is passed.

For more, see 'Callback Notes' in the package comment.

func (*GoPromise) Delay added in v0.3.0

func (p *GoPromise) Delay(d time.Duration, onSucceed, onFail bool) Promise

Delay returns a GoPromise value which will be resolved to this GoPromise( by adopting its Res value, state, and fate), after a delay of at least duration d. The delay starts after this GoPromise is resolved, accordingly.

If this promise is resolved to fulfilled or pending, resolving the returned promise will be delayed, only if onSucceed = true.

If this promise is resolved to rejected or panicked, resolving the returned promise will be delayed, only if onFail = true.

If the promise is running in the safe mode(the default), the returned Promise is a rejected promise, and the error is not caught(by a Catch call) before the end of that promise's chain, a panic will happen with an error value of type *UnCaughtErr, which has that uncaught error 'wrapped' inside it.

If the returned promise is a panicked promise, and it's not recovered(by a Recover call) before the end of the promise's chain, or before calling Finally, it will re-panic(with the same value passed to the original 'panic' call).

func (*GoPromise) Finally

func (p *GoPromise) Finally(finallyCb func(ok bool) Res) Promise

Finally waits the promise to be resolved, and calls the finallyCb function, regardless the promise is rejected, panicked, or neither.

If the promise has panicked, it must be handled(either sequentially, or in-parallel) before calling this method, otherwise the promise will re-panic before this call.

It returns a GoPromise value, which will be resolved to this promise's result, if the finallyCb returned a nil Res value. If the finallyCb returned a non-nil Res value, the returned promise will be resolved to that returned Res value.

The Res value returned from the callback must not be modified after return.

The finallyCb is passed with one arguments, a boolean, ok, which will always be true.

It will panic if a nil callback is passed.

For more, see 'Callback Notes' in the package comment.

func (*GoPromise) GetRes

func (p *GoPromise) GetRes() (res Res, ok bool)

GetRes waits the promise to be resolved, and returns its result, res, and ok = true, if the promise hasn't panicked, otherwise it returns res = nil, and ok = false.

func (*GoPromise) Recover

func (p *GoPromise) Recover(recoverCb func(v interface{}, ok bool) Res) Promise

Recover waits the promise to be resolved, and calls the recoverCb function, if the promise is resolved to panicked.

It returns a GoPromise value whose result will be the Res value returned from the recoverCb.

The Res value returned from the callback must not be modified after return.

The recoverCb is passed with two arguments, the value that was passed to the 'panic' call which caused this promise to be panicked, v, and a boolean, ok, which will always be true.

It will panic if a nil callback is passed.

For more, see 'Callback Notes' in the package comment.

func (*GoPromise) Status added in v0.3.0

func (p *GoPromise) Status() Status

Status returns the status of this promise at this specific moment.

The returned value corresponds only to the time it was created at.

func (*GoPromise) Then

func (p *GoPromise) Then(thenCb func(res Res, ok bool) Res) Promise

Then waits the promise to be resolved, and calls the thenCb function, if the promise is resolved to fulfilled or pending.

It returns a GoPromise value whose result will be the Res value returned from the thenCb.

The Res value returned from the callback must not be modified after return.

The thenCb is passed with two arguments, this promise's result, res, and a boolean, ok, which will always be true.

It will panic if a nil callback is passed.

For more, see 'Callback Notes' in the package comment.

func (*GoPromise) Wait

func (p *GoPromise) Wait() (ok bool)

Wait waits the promise to be resolved. It returns false, if the promise has panicked, otherwise it returns true.

func (*GoPromise) WaitChan

func (p *GoPromise) WaitChan() chan bool

WaitChan returns a newly created channel, which true will be sent on, for only one time, after waiting the promise to be resolved.

If it's called on a resolved promise, true will be sent without waiting.

type Promise

type Promise interface {
	// Status returns the status of this promise at this specific moment.
	//
	// The returned value corresponds only to the time it was created at.
	Status() Status

	// Wait waits the promise to be resolved. It returns false, if the promise
	// has panicked, otherwise it follows the rules of the underlying Promise
	// implementation.
	//
	// If the underlying Promise implementation is the GoPromise, and it's not
	// panicked, then ok will always = true.
	Wait() (ok bool)

	// WaitChan returns a newly created channel, which a boolean value will be
	// sent on, for only one time, after waiting the promise to be resolved.
	// The sent value correspond to the return of the Wait method.
	//
	// If it's called on a resolved promise, the value will be sent without
	// waiting.
	WaitChan() chan bool

	// GetRes waits the promise to be resolved, and returns its result, res,
	// and a boolean, ok, which will be true only if res is valid.
	//
	// The res value will be invalid(ok = false), if the promise has panicked,
	// otherwise it follows the rules of the underlying Promise implementation.
	//
	// If the underlying Promise implementation is the GoPromise, and it's not
	// panicked, then the res value will always be valid(ok = true).
	GetRes() (res Res, ok bool)

	// Delay returns a Promise value which will be resolved to this Promise(
	// by adopting its Res value, state, and fate), after a delay of at least
	// duration d. The delay starts after this Promise is resolved, accordingly.
	//
	// If this promise is resolved to fulfilled or pending, resolving the returned
	// promise will be delayed, only if onSucceed = true.
	//
	// If this promise is resolved to rejected or panicked, resolving the returned
	// promise will be delayed, only if onFail = true.
	//
	// If the promise is running in the safe mode(the default), the returned
	// Promise is a rejected promise, and the error is not caught(by a Catch call)
	// before the end of that promise's chain, a panic will happen with an error
	// value of type *UnCaughtErr, which has that uncaught error 'wrapped' inside it.
	//
	// If the returned promise is a panicked promise, and it's not recovered(by a
	// Recover call) before the end of the promise's chain, or before calling Finally,
	// it will re-panic(with the same value passed to the original 'panic' call).
	Delay(d time.Duration, onSucceed, onFail bool) Promise

	// Then waits the promise to be resolved, and calls the thenCb function, if
	// the promise is resolved to fulfilled or pending(the promise didn't return
	// an error nor caused a panic).
	//
	// It returns a Promise value, which will be resolved to the Res value
	// returned from the thenCb.
	//
	// The Res value returned from the callback must not be modified after return.
	//
	// The thenCb is passed with two arguments, this promise's result, res, and
	// a boolean, ok, which will be true, only if res is valid.
	//
	// The res parameter will always be valid(and ok = true), if the underlying
	// Promise implementation is the GoPromise.
	//
	// The ok parameter's value(and the validity of other parameter) will
	// follow the rules of each of the other Promise implementations(other
	// than GoPromise), which are described at their methods.
	//
	// It will panic if a nil callback is passed.
	//
	// For more details, see 'Callback Notes' in the package comment.
	Then(thenCb func(res Res, ok bool) Res) Promise

	// Catch waits the promise to be resolved, and calls the catchCb function,
	// if the promise is resolved to rejected(the promise returned an error).
	//
	// It returns a Promise value, which will be resolved to the Res value
	// returned from the catchCb.
	//
	// The Res value returned from the callback must not be modified after return.
	//
	// The catchCb is passed with three arguments, the error that caused this
	// promise to be rejected, err, this promise's result, res(including the
	// error at the end), and a boolean, ok, which will be true, only if err,
	// and res, are valid.
	//
	// The err, and the res parameters will always be valid(and ok = true), if
	// the underlying Promise implementation is the GoPromise.
	//
	// The ok parameter's value(and the validity of other parameters) will
	// follow the rules of each of the other Promise implementations(other
	// than GoPromise), which are described at their methods.
	//
	// The result is passed here with the error, because, in Go, errors are
	// just values, so returning them is not always considered an unwanted
	// behaviour(example: io.EOF error), so some logic may depend on both.
	//
	// Note that if the catchCb returned the res as-is, the returned promise
	// will be rejected also(because there's a non-nil error at its end).
	//
	// It will panic if a nil callback is passed.
	//
	// For more details, see 'Callback Notes' in the package comment.
	Catch(catchCb func(err error, res Res, ok bool) Res) Promise

	// Recover waits the promise to be resolved, and calls the recoverCb function,
	// if the promise is resolved to panicked(the promise caused a panic).
	//
	// It returns a Promise value, which will be resolved to the Res value
	// returned from the recoverCb.
	//
	// The Res value returned from the callback must not be modified after return.
	//
	// The recoverCb is passed with two arguments, the value that was passed
	// to the 'panic' call which caused this promise to be panicked, v, and a
	// boolean, ok, which will be true, only if v is valid.
	//
	// The v parameter will always be valid(and ok = true), if the underlying
	// Promise implementation is the GoPromise.
	//
	// The ok parameter's value(and the validity of other parameter) will
	// follow the rules of each of the other Promise implementations(other
	// than GoPromise), which are described at their methods.
	//
	// It will panic if a nil callback is passed.
	//
	// For more details, see 'Callback Notes' in the package comment.
	Recover(recoverCb func(v interface{}, ok bool) Res) Promise

	// Finally waits the promise to be resolved, and calls the finallyCb function,
	// regardless the promise is rejected, panicked, or neither.
	//
	// If the promise has panicked, it must be handled(either sequentially, or
	// in-parallel) before calling this method, otherwise the promise will
	// re-panic before this call.
	//
	// It returns a Promise value, which will be resolved to this promise's
	// result, if the finallyCb returned a nil Res value.
	// If the finallyCb returned a non-nil Res value, the returned Promise
	// will be resolved to that returned Res value.
	//
	// The Res value returned from the callback must not be modified after return.
	//
	// The finallyCb is passed with one arguments, a boolean, ok, which will
	// always be true, if the underlying Promise implementation is the GoPromise,
	// and the promise hasn't panicked.
	// But, if the underlying Promise implementation is the GoPromise, and the
	// promise has panicked, ok will be false.
	//
	// The ok parameter's value will follow the rules of each of the other
	// Promise implementations(other than GoPromise), which are described
	// at their methods.
	//
	// It will panic if a nil callback is passed.
	//
	// For more details, see 'Callback Notes' in the package comment.
	Finally(finallyCb func(ok bool) Res) Promise
	// contains filtered or unexported methods
}

Promise represents some asynchronous work. It offer ways to get the eventual result of that work, and/or build a computation pipeline assuming that result is known.

The default implementation for this interface is the GoPromise type.

It's a private interface, which can only be implemented by embedding any type that implement it from this module.

type Res

type Res []interface{}

Res is the type of the return value returned from all callbacks. It represents the return parameters of functions/methods in Go, and as they can be multiple return parameters, the returned values are represented here as a slice of values.

It follows the convention of passing the error, if any, as the last parameter in the return parameters list, which is represented here as the last element in the slice. So, if a callback returned a non-nil error value as the last element in the returned Res value, the returned Promise will be a 'rejected' promise.

Values of this type must not be modified after returned from any callback.

func ImmutRes

func ImmutRes(vals ...interface{}) (res Res)

ImmutRes takes the to-be-returned values, vals, add them to a new Res value, and returns the newly allocated Res value.

It effectively copies the provided slice of values, vals, into a new Res value, so if it's passed with a slice, the returned Res value will be immutable, meaning that, modifying the passed slice will not modify the returned Res value.

It should be used only inside callbacks, and when the to-be-returned Res value is not created at return site and maybe modified after return, or when that Res value is retrieved from another function that may modify it after return.

Example:

 // inside any callback..
 // ('getMyRes' is any function that returns a Res value, and
 // may modify the value after it's returned from this callback.)
 myRes := getMyRes()

	/* update 'myRes' (or do other work) */

 // when returning, don't return 'myRes' directly, like:
 return myRes
 // instead, return it through ImmutRes, as follows:
	return promise.ImmutRes(myRes...)

func MustGetRes

func MustGetRes(p Promise) (res Res)

MustGetRes calls GetRes on the provided promise, and returns its result, only if the returned ok value = true, otherwise, it panics.

By name convention, the function will return the result successfully(ok = true), or a panic will happen. This functions should be used on promises which their GetRes methods are known to always return ok = true(GoPromise with no 'Recover' follow).

func ReuseRes added in v0.2.0

func ReuseRes(base Res, vals ...interface{}) (res Res)

ReuseRes takes a Res value, base, and repopulate it with the provided values, vals, only if it can hold them, and returns it. Otherwise, a new Res value will be allocated, populated with vals, and returned.

The provided base will be populated with the provided values, if its capacity is less than or equal to the length of the provided values. Otherwise, it will not be touched.

If no values are provided, it will return nil, without touching the base.

It should be used only inside callbacks, and when the provided Res value, base, is not needed any more(before this call), and the number of the to-be-returned values is less than the base's capacity.

It only serves as a way to minimize memory allocations when the number of values returned from a callback is the same as the length of the Res value passed to the callback, by reusing that Res value(under the above conditions). However, it will always return a Res value that contain the passed values, vals, so it can be used as a general return function which can, when appropriate, optimize memory allocations.

Example:

 // inside any callback..
 // ('res' is the Res value passed to the callback)

	/* after done needing 'res' */

 // ('val1, val2, ..., valN' are any values)
 // when returning the following values, val1, val2, ..., valN,
 // and N is less than or equal cap(res), don't return them like:
 return promise.Res{val1, val2, ..., valN}
 // instead, return them through ReuseRes, as follows:
	return promise.ReuseRes(res, val1, val2, ..., valN)

func (Res) Clear added in v0.2.0

func (res Res) Clear() (n int)

Clear sets all elements of this Res value to nil, and returns its length.

func (Res) Copy added in v0.2.0

func (res Res) Copy() (newRes Res)

Copy returns a new copy of this Res value if it's not empty, otherwise returns this Res value.

func (Res) Err added in v0.4.0

func (res Res) Err() (err error, isError bool)

Err checks if the last element of this Res value is a non-nil error value and returns the error value and true, otherwise it returns nil and false.

It returns nil and false if this Res value is empty, the type of the last element is not error, or the last element is a nil error value.

func (Res) First added in v0.2.0

func (res Res) First() (first interface{}, ok bool)

First returns the first element of this Res value and true, if its length is not 0, otherwise it returns nil and false.

func (Res) GetErr

func (res Res) GetErr() error

GetErr returns the last element of this Res value, if its type is error. It returns nil if this Res value is empty or the type of the last element is not error. Deprecated: Use the err return parameter of the Err method instead.

func (Res) IsErrRes

func (res Res) IsErrRes() bool

IsErrRes returns true if this Res value represents an error result, which is a result that has a non-nil error as its last element. Deprecated: Use the isError return parameter of the Err method instead.

func (Res) IsZero added in v0.2.0

func (res Res) IsZero() bool

IsZero returns true if this Res value has no elements, or if all of its elements are nil, otherwise it returns false.

func (Res) Last

func (res Res) Last() (last interface{}, ok bool)

Last returns the last element of this Res value and true, if its length is not 0, otherwise it returns nil and false.

type Status added in v0.3.0

type Status uint32

Status holds the state and the fate info of the corresponding Promise, at the time it is created.

func (Status) Fate added in v0.3.0

func (s Status) Fate() string

Fate returns the fate of the promise.

For more info, see 'States and Fates' in the package comment.

func (Status) IsFulfilled added in v0.3.0

func (s Status) IsFulfilled() bool

IsFulfilled returns true, only if the state of the promise is Fulfilled.

For more info, see 'States and Fates' in the package comment.

func (Status) IsHandled added in v0.3.0

func (s Status) IsHandled() bool

IsResolved returns true, only if the fate of the promise is Handled.

For more info, see 'States and Fates' in the package comment.

func (Status) IsPanicked added in v0.3.0

func (s Status) IsPanicked() bool

IsPanicked returns true, only if the state of the promise is Panicked.

For more info, see 'States and Fates' in the package comment.

func (Status) IsPending added in v0.3.0

func (s Status) IsPending() bool

IsPending returns true, only if the state of the promise is Pending.

For more info, see 'States and Fates' in the package comment.

func (Status) IsRejected added in v0.3.0

func (s Status) IsRejected() bool

IsRejected returns true, only if the state of the promise is Rejected.

For more info, see 'States and Fates' in the package comment.

func (Status) IsResolved added in v0.3.0

func (s Status) IsResolved() bool

IsResolved returns true, only if the fate of the promise is Resolved or Handled.

For more info, see 'States and Fates' in the package comment.

func (Status) State added in v0.3.0

func (s Status) State() string

State returns the state of the promise.

For more info, see 'States and Fates' in the package comment.

type UnCaughtErr

type UnCaughtErr struct {
	// contains filtered or unexported fields
}

UnCaughtErr wraps an error that happened in a promise chain, but hasn't been caught, by the end of that chain.

func (*UnCaughtErr) Error

func (e *UnCaughtErr) Error() string

func (*UnCaughtErr) Unwrap

func (e *UnCaughtErr) Unwrap() error

Directories

Path Synopsis
examples
asyncHttp command
ctxProm command
goWithRecover command
goWithReturn command
resolver command
timers command
waitgroup command
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL