There are two ways to create async functions: creating latent functions and making functions that take dynamic delegates as parameters and execute them later.
Dynamic delegate parameters require less boilerplate code and allow async functionality to be used inside functions (by using the “create event” node), but since you need to store the delegate somewhere to call it later it’s better suited for object methods where you tell an object to do something and have it fire the callback later. Check the docs here to see how they work: https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/Delegates/index.html#declaringdelegates
You basically declare your delegate signature and function like this:
DECLARE_DYNAMIC_DELEGATE_OneParam(FRemoteImageLoaderOnCompleteBP, UTexture2D*, Texture);
UFUNCTION(BlueprintCallable, Category = "Image")
static URemoteImageLoader* LoadImageFromURL(const FString& ImageUrl, FRemoteImageLoaderOnCompleteBP Callback);
Then when you are done, call the “Callback” that was passed to the function like this:
// "Texture" is a UTexture*
The blueprint ends up looking like this:
Now, about latent functions. Those require you to create a class that derives from FPendingLatentAction to encapsulate all aspects of the “task” you are performing, so they are better suited for blueprint function library functions that can be called anywhere. The actions are added to the world’s LatentActionManager and are “ticked” so they can report whether they finished or not. They can also provide a human-readable status (it’s the text that shows up when you are watching a blueprint run live, like the delay node countdown). Just look at how Delay (UKismetSystemLibrary::Delay) and RetriggerableDelay are implemented (UKismetSystemLibrary::RetriggerableDelay) in KismetSystemLibrary and you should get a good idea how it works.
BTW, if you need to return a result it’s better to use delegates, since you can’t simply return a value from a latent function (it is possible to do it by using pointers to references, but it requires extra code to keep it safe).