promise-cpp is header only and easy to use, just #include "promise.hpp" is enough. With promise-cpp, you can resolve or reject any type of data without writing complex template code.
#include <stdio.h>
#include <string>
#include "promise.hpp"
using namespace promise;
#define output_func_name() do{ printf("in function %s, line %d\n", __func__, __LINE__); } while(0)
void test1() {
output_func_name();
}
int test2() {
output_func_name();
return 5;
}
void test3(int n) {
output_func_name();
printf("n = %d\n", n);
}
Defer run(Defer &next){
return newPromise([](Defer d){
output_func_name();
d.resolve(3, 5, 6);
}).then([](const int &a, int b, int c) {
printf("%d %d %d\n", a, b, c);
output_func_name();
}).then([](){
output_func_name();
}).then([&next](){
output_func_name();
next = newPromise([](Defer d) {
output_func_name();
});
//Will call next.resole() or next.reject() later
return next;
}).then([](int n, char c) {
output_func_name();
printf("n = %d, c = %c\n", (int)n, c);
}).fail([](char n){
output_func_name();
printf("n = %d\n", (int)n);
}).fail([](short n) {
output_func_name();
printf("n = %d\n", (int)n);
}).fail([](int &n) {
output_func_name();
printf("n = %d\n", (int)n);
}).fail([](const std::string &str) {
output_func_name();
printf("str = %s\n", str.c_str());
}).fail([](uint64_t n) {
output_func_name();
printf("n = %d\n", (int)n);
}).then(test1)
.then(test2)
.then(test3)
.always([]() {
output_func_name();
});
}
int main(int argc, char **argv) {
Defer next;
run(next);
printf("====== after call run ======\n");
next.resolve(123, 'a');
//next.reject('c');
//next.reject(std::string("xhchen"));
//next.reject(45);
return 0;
}
Creates a new Defer object with a user-defined function. The user-defined functions, used as parameters by newPromise, must have a parameter Defer d. for example --
return newPromise([](Defer d){
})
Returns a promise that is resolved with the given value. for example --
return resolve(3, '2');
Returns a promise that is rejected with the given arguments. for example --
return reject("some_error");
Defer object is the promise object itself.
Resolve the promise object with arguments, where you can put any number of ret_arg with any type. (Please be noted that it is a method of Defer object, which is different from the global resolve function.) for example --
return newPromise([](Defer d){
//d.resolve();
//d.resolve(3, '2', std::string("abcd"));
d.resolve(9567);
})
Reject the promise object with arguments, where you can put any number of ret_arg with any type. (Please be noted that it is a method of Defer object, which is different from the global resolve function.) for example --
return newPromise([](Defer d){
//d.reject();
//d.reject(std::string("oh, no!"));
d.reject(-1, std::string("oh, no!"))
})
Return the chaining promise object, where on_resolved is the function to be called when previous promise object calls function resolve, on_rejected is the function to be called when previous promise object calls function reject. for example --
return newPromise([](Defer d){
d.resolve(9567, 'A');
}).then(
/* function on_resolved */ [](int n, char ch){
printf("%d %c\n", n, ch); //will print 9567 here
},
/* function on_rejected */ [](){
});
Return the chaining promise object, where on_resolved is the function to be called when previous promise object calls function resolve. for example --
return newPromise([](Defer d){
d.resolve(9567);
}).then([](int n){
printf("%d\n", n); b //will print 9567 here
});
Return the chaining promise object, where on_rejected is the function to be called when previous promise object calls function reject.
This function is usually named "catch" in most implements of Promise library. https://www.promisejs.org/api/
In promise_cpp, function name "fail" is used instead of "catch", since "catch" is a keyword of c++.
for example --
return newPromise([](Defer d){
d.reject(-1, std::string("oh, no!"));
}).fail([](int err, string &str){
printf("%d, %s\n", err, str.c_str()); //will print "-1, oh, no!" here
});
Return the chaining promise object, where on_finally is the function to be called whenever the previous promise object is be resolved or rejected.
The returned promise object will keeps the resolved/rejected state of current promise object.
for example --
return newPromise([](Defer d){
d.reject(std::string("oh, no!"));
}).finally([](){
printf("in finally\n"); //will print "in finally" here
});
Return the chaining promise object, where on_always is the function to be called whenever the previous promise object is be resolved or rejected.
The returned promise object will be in resolved state whenever current promise object is resolved or rejected.
for example --
return newPromise([](Defer d){
d.reject(std::string("oh, no!"));
}).always([](){
printf("in always\n"); //will print "in always" here
});
To throw any object in the callback functions above, including on_resolved, on_rejected, on_always, will same as d.reject(the_throwed_object) and returns immediately. for example --
return newPromise([](Defer d){
throw std::string("oh, no!");
}).fail([](string &str){
printf("%s\n", str.c_str()); //will print "oh, no!" here
});
For the performance, we suggest to use function reject instead of throw.
Any type of parameter can be used when call resolve, reject or throw, except that the plain string or array. To use plain string or array as chaining parameters, we may wrap it into an object.
newPromise([](Defer d){
// d.resolve("ok"); may cause a compiling error, use the following code instead.
d.resolve(std::string("ok"));
})
To copy the promise object is allowed and effective, please do that when you need.
Defer d = newPromise([](Defer d){});
Defer d1 = d; //It's safe and effective