我正在尝试为c ++编写一个类似es6 Promise的类而不使用外部库(在我的项目中我不能使用boost或std lib )
我遇到了处理已经解决或被拒绝的承诺的回调的麻烦。因为我想链接不同的已解析值类型,所以我无法指定类型。
我有2个类来处理这个承诺。 延迟用于解析值或拒绝承诺,承诺用于链接回调函数(promises)。为了便于阅读,我省略了一些代码。
推迟上课:
class Defer
{
public:
Defer(Promise *promise) : Defer(promise, NULL, NULL) {};
Defer(Promise *promise, static_deferred_callback<> onResolved) : Defer(promise, onResolved, NULL) {};
Defer(Promise *promise, static_deferred_callback<> onResolved, static_defered_callback<> onRejected) :
promise(promise),
onResolved(onResolved),
onRejected(onRejected) {};
virtual ~Defer() { };
template <typename ...Args>
inline void resolve(Args&&... args)
{
if (onResolved)
{
((static_deferred_callback<Args...>)onResolved)(promise, args...);
}
};
// inline void resolve(Promise<T> &p); continue chain w/ new promise
inline void reject()
{
if (onRejected)
{
onRejected(promise);
}
};
private:
Promise *promise;
static_deferred_callback<> onResolved = 0;
static_deferred_callback<> onRejected = 0;
};
承诺课程:
class Promise
{
public:
Promise(new_promise promise) : defer(new Defer(this, Promise::OnPromiseResolved<>)), size(0), currentIndex(0)
{
this->promised = promise;
};
virtual ~Promise() { };
/* ... */
inline Promise& run()
{
if (!hasRun && promised)
{
hasRun = true;
Defer d = *defer;
promised(d);
}
return *this;
};
private:
template <typename ...Args>
static deferred_callback<Args...> OnPromiseResolved(Promise *promise, Args&&... x)
{
// problem lies here,
// param 'x' yields no values at this point.
// if (promise && !promise->rejected)
// {
// promise->next(x...);
// }
};
template <typename ...Args>
static deferred_callback<Args...> OnPromiseRejected(Promise *promise, Args... x)
{
if (promise && !promise->rejected)
{
promise->rejected = true;
promise->onFailed();
}
};
template <typename ...Args>
inline void call(next_promise<Args...> promise, Args &&... x)
{
if (promise)
{
Defer d = *defer;
promise(d, x...);
}
};
template <typename ...Args>
inline void next(Args &&... x)
{
if (!isFinished && (currentIndex == size || rejected))
{
isFinished = true;
if (!rejected && onSuccess)
{
onSuccess(x...);
}
if (onAlways)
{
onAlways(rejected, x...);
}
}
if (!rejected && currentIndex < size)
{
call(chain[currentIndex++], x...);
}
};
bool rejected = false;
bool hasRun = false;
bool isFinished = false;
new_promise promised;
next_promise<> chain[64]; // temporary fixed size
resolved_function<> onSuccess = 0;
anonymous_function onFailed = 0;
finished_promise<> onAlways = 0;
size_t size;
size_t currentIndex;
Defer *defer;
};
输入defs:
using new_promise = void (*)(Defer);
template <typename ...Args>
using next_promise = void (*)(Defer, Args...);
template <typename ...Args>
using resolved_promise = void (*)(Args...);
template <typename ...Args>
using finished_promise = void (*)(bool, Args...);
template <typename ...Args>
using deferred_callback = void (*)(Promise*, Args...);
template <typename ...Args>
using static_deferred_callback = void (* (*)(Promise*, Args...))(Promise*, Args...);
目前,类型定义完全混乱。我使用多个类型定义来指定我的Promise实现所需的回调函数的类型。
样本用法:
int main()
{
Promise promise = Promise([](Defer defer) {
defer.resolve(11, 22, 33);
})
// .then([](Defer defer, int a, int b, int c) {
// defer.resolve(a + b + c);
// })
.run();
return 0;
}
我遇到的问题是指定处理已解决状态的函数( Promise :: OnPromiseResolved )必须接受任何类型(template <...Args>
)。我可以从返回的Defer对象中解析任何和多个值( Defer :: resolve )。当我在Defer对象上调用resolve方法时,会传递值。接下来,我想将这些值发送到我存储在Defer对象中的Promise对象。但是,当我在Defer类中调用指向函数( onResolved )的指针时,当类型任何>时,包扩展表达式不会将值转发到回调上强>
如果我明确地将它设置为我在指定的回调函数中解析的类型,我可以使用Defer对象的resolve方法检索我传递的值(例如我解析2个整数,参数承诺类中的方法 OnPromiseResolved 必须更改为2个整数而不是参数包。但这使得无法解析可解析的类型。
如果其中任何一项没有太多意义,请不要犹豫,要求进一步澄清。