Created
May 4, 2018 20:56
-
-
Save galvesribeiro/fd3d9e7996a0787f880dc864b01e75f5 to your computer and use it in GitHub Desktop.
Blazor Promises
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IPromiseCallbackHandler | |
{ | |
void SetResult(string json); | |
void SetError(string error); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PromiseCallbackHandler<TResult> : IPromiseCallbackHandler | |
{ | |
private readonly TaskCompletionSource<TResult> _tcs; | |
public PromiseCallbackHandler(TaskCompletionSource<TResult> tcs) | |
{ | |
this._tcs = tcs; | |
} | |
public void SetResult(string json) | |
{ | |
TResult result = JsonUtil.Deserialize<TResult>(json); | |
this._tcs.SetResult(result); | |
} | |
public void SetError(string error) | |
{ | |
var exception = new Exception(error); | |
this._tcs.SetException(exception); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class Promises | |
{ | |
private const string PROXY_FUNCTION = "GP.Portal.Utils.Promises.Proxy"; | |
private static ConcurrentDictionary<string, IPromiseCallbackHandler> _callbackHandlers = | |
new ConcurrentDictionary<string, IPromiseCallbackHandler>(); | |
public static void PromiseCallback(string callbackId, string result) | |
{ | |
if (_callbackHandlers.TryGetValue(callbackId, out IPromiseCallbackHandler handler)) | |
{ | |
handler.SetResult(result); | |
_callbackHandlers.TryRemove(callbackId, out IPromiseCallbackHandler _); | |
} | |
} | |
public static void PromiseError(string callbackId, string error) | |
{ | |
if (_callbackHandlers.TryGetValue(callbackId, out IPromiseCallbackHandler handler)) | |
{ | |
handler.SetError(error); | |
_callbackHandlers.TryRemove(callbackId, out IPromiseCallbackHandler _); | |
} | |
} | |
public static Task<TResult> ExecuteAsync<TResult>(string fnName, object data = null) | |
{ | |
var tcs = new TaskCompletionSource<TResult>(); | |
string callbackId = Guid.NewGuid().ToString(); | |
if (_callbackHandlers.TryAdd(callbackId, new PromiseCallbackHandler<TResult>(tcs))) | |
{ | |
if (data == null) | |
{ | |
RegisteredFunction.Invoke<bool>(PROXY_FUNCTION, callbackId, fnName); | |
} | |
else | |
{ | |
RegisteredFunction.Invoke<bool>(PROXY_FUNCTION, callbackId, fnName, data); | |
} | |
return tcs.Task; | |
} | |
throw new Exception("An entry with the same callback id already existed, really should never happen"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const PromisesProxy = {}; | |
const assemblyName = 'GP.Portal.Utils'; | |
const namespace = 'GP.Portal.Utils'; | |
const typeName = 'Promises'; | |
const methodName = 'PromiseCallback'; | |
const errorMethodName = 'PromiseError'; | |
Blazor.registerFunction('GP.Portal.Utils.Promises.Proxy', (callbackId, fnName, data) => { | |
const callbackMethod = Blazor.platform.findMethod( | |
assemblyName, | |
namespace, | |
typeName, | |
methodName | |
); | |
const errorCallbackMethod = Blazor.platform.findMethod( | |
assemblyName, | |
namespace, | |
typeName, | |
errorMethodName | |
); | |
let promise = PromisesProxy[fnName](data); | |
promise.then(value => { | |
if (value === undefined) { | |
value = null; | |
} | |
const result = JSON.stringify(value); | |
Blazor.platform.callMethod( | |
callbackMethod, | |
null, | |
[ | |
Blazor.platform.toDotNetString(callbackId), | |
Blazor.platform.toDotNetString(result) | |
] | |
); | |
}).catch(reason => { | |
if (!reason) { | |
reason = "Something went wrong"; | |
} | |
const result = reason.toString(); | |
Blazor.platform.callMethod( | |
errorCallbackMethod, | |
null, | |
[ | |
Blazor.platform.toDotNetString(callbackId), | |
Blazor.platform.toDotNetString(result) | |
] | |
); | |
}); | |
// Your function currently has to return something. | |
return true; | |
}); | |
PromisesProxy.Test = () => { | |
console.log("1"); | |
return new Promise((resolve, reject) => { | |
console.log("2"); | |
setTimeout(() => { | |
console.log("3"); | |
resolve("From JS!"); | |
}, 1000); | |
console.log("4"); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment