Skip to content

Instantly share code, notes, and snippets.

@grifdail
Last active December 11, 2017 11:04
Show Gist options
  • Save grifdail/5d8db2cc3d8bb34358a501020cf021ae to your computer and use it in GitHub Desktop.
Save grifdail/5d8db2cc3d8bb34358a501020cf021ae to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class ExemplePromise : MonoBehaviour {
public int Pokemon1 = 1;
public int Pokemon2 = 2;
private void OnGUI() {
if(GUI.Button(new Rect(400, 0, 200, 100), "calc biggest pokemon promise")) {
GetBiggestPokemon(Pokemon1, Pokemon2);
}
}
void GetBiggestPokemon(int id1, int id2) {
Debug.Log("hello");
PokemonData firstPokemon = null;
PokemonData secondPokemon = null;
GetPokemon(id1)
.Then<PokemonData>(_pk1 => {
Debug.Log("First pokemon is " + _pk1.name);
firstPokemon = _pk1;
return GetPokemon(Pokemon2);
})
.Then(_pk2 => {
Debug.Log("Second pokemon is " + _pk2.name);
secondPokemon = _pk2;
PokemonData biggest = firstPokemon.weight > secondPokemon.weight ? firstPokemon : secondPokemon;
Debug.Log("Biggest pokemon is " + biggest.name);
})
.Catch(_err => Debug.Log(_err.Message));
}
// Make a request to the pokemon api, parse it and resolve with a PokemonData
Promise<PokemonData> GetPokemon(int id) {
return Request("http://pokeapi.co/api/v2/pokemon/" + id)
.Then(JsonUtility.FromJson<PokemonData>);
}
Promise<string> Request(string _url) {
var p = new Promise<string>();
StartCoroutine(RequestCoroutine(_url, p));
return p;
}
IEnumerator RequestCoroutine(string url, Deferred<string> _deferred) {
WWW request = new WWW(url);
yield return request;
if(request.isDone && request.error == null) {
_deferred.Resolve(request.text);
} else {
_deferred.Throw(request.error);
}
}
}
using System;
/// <summary>
/// Same as a deferredCallback but we can add callback after the initialisation and we can chain multiple promise;
/// </summary>
/// <typeparam name="T"></typeparam>
class Promise<T> : DeferredCallback<T> {
/// <summary>
/// Add a callback that will be called if there's an AsyncError somewhere in the promise chain
/// return the promise itself so we can add more callback
/// </summary>
/// <param name="_func"></param>
/// <returns></returns>
public Promise<T> Catch(Action<AsyncError> _func) {
if(IsCompleted && Error != null) {
_func(Error);
} else {
onError += _func;
}
return this;
}
/// <summary>
/// Then add a callback that will be executed when the promise is resolved;
/// Return the promise itself so we can add more callback
/// </summary>
/// <param name="_func"></param>
/// <returns></returns>
public Promise<T> Then(Action<T> _func) {
if(IsCompleted && Error == null) {
_func(Value);
} else {
onResolve += _func;
}
return this;
}
/// <summary>
/// If we pass a function that return a new transformed value; We return a new promise that is resolved with that value
/// Error are passed through
/// </summary>
/// <typeparam name="U"></typeparam>
/// <param name="_func"></param>
/// <returns></returns>
public Promise<U> Then<U>(Func<T, U> _func) {
var t = new Promise<U>();
Then((T _value) => {
t.Resolve(_func(_value));
});
Catch(_error => t.Throw(_error));
return t;
}
/// <summary>
/// If we pass a function that return a promise; we return a new promise that will be resolved when that promise resolve with that promise value
/// Error are passed through
/// </summary>
/// <typeparam name="U"></typeparam>
/// <param name="_func"></param>
/// <returns></returns>
public Promise<U> Then<U>(Func<T, Promise<U>> _func) {
var t = new Promise<U>();
Then((T _value) => {
var d = _func(_value);
d.Then(nestedValue => t.Resolve(nestedValue));
d.Catch(_err => t.Throw(_err));
});
Catch(_error => t.Throw(_error));
return t;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment