async

std::async() is a function template that accepts a callback(i.e. function or function object) as an argument and potentially executes them asynchronously.
```
template <class Fn, class... Args>
future<typename result_of<Fn(Args...)>::type> async (launch policy, Fn&& fn, Args&&... args);
```
std::async returns a std::future<T>, that stores the value returned by function object executed by std::async(). Arguments expected by function can be passed to std::async() as arguments after the function pointer argument.
First argument in std::async is launch policy, it control the asynchronous behavior of std::async. We can create std::async with 3 different launch policies i.e.
* std::launch::async: It guarantees the asynchronous behaviour i.e. passed function will be executed in seperate thread.
* std::launch::deferred: Non asynchronous behaviour i.e. Function will be called when other thread will call get() on future to access the shared state. 
* std::launch::async | std::launch::deferred: Its the default behaviour. With this launch policy it can run asynchronously or not depending on the load on system. But we have no control over it.

If we do not specify an launch policy. Its behaviour will be similar to std::launch::async | std::launch::deferred.
We can pass any callback in std::async i.e.
* Function Pointer
* Function Object
* Lambda Function

std::async() does following things,
* It automatically creates a thread (Or picks from internal thread pool) and a promise object for us.
* Then passes the std::promise object to thread function and returns the associated std::future object.
* When our passed argument function exits then its value will be set in this promise object, so eventually return value will be available in std::future object.
```
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
using namespace std;
using namespace std::chrono;

string fetchDataFromDB(string data) {
    this_thread::sleep_for(seconds(3));
    return "DB_" + data;
}

string fetchDataFromFile(string data){
    this_thread::sleep_for(seconds(3));
    return "File_" + data;
}

int main() {
    future<string> resultFromDB = async(launch::async, fetchDataFromDB, "Data");
    future<string> resultFromFile = async(launch::async, fetchDataFromFile, "Data");
    string dbData = resultFromDB.get();
    string fileData = resultFromFile.get();

    string data = dbData + " :: " + fileData;
    cout << "Data = " << data << endl;
    return 0;
}
```