1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_DOMMozPromiseRequestHolder_h
8 #define mozilla_dom_DOMMozPromiseRequestHolder_h
10 #include "mozilla/DOMEventTargetHelper.h"
11 #include "mozilla/MozPromise.h"
13 namespace mozilla::dom
{
16 * This is a helper class that can be used when MozPromises are
17 * being consumed by binding layer code. It effectively creates
18 * a MozPromiseRequestHolder that auto-disconnects when the binding's
19 * global is disconnected.
21 * It can be used like this:
24 * SomeAsyncAPI(Args& aArgs, ErrorResult& aRv)
26 * nsIGlobalObject* global = GetParentObject();
28 * aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
32 * RefPtr<Promise> outer = Promise::Create(global, aRv);
37 * RefPtr<DOMMozPromiseRequestHolder> holder =
38 * new DOMMozPromiseRequestHolder(global);
40 * DoAsyncStuff()->Then(
41 * global->EventTargetFor(TaskCategory::Other), __func__,
42 * [holder, outer] (const Result& aResult) {
45 * // Note, you can access the holder's bound global in
46 * // your reaction handler. Its mostly likely set if
47 * // the handler fires, but you still must check for
48 * // its existence since something could disconnect
49 * // the global between when the MozPromise reaction
50 * // runnable is queued and when it actually runs.
51 * nsIGlobalObject* global = holder->GetParentObject();
52 * NS_ENSURE_TRUE_VOID(global);
54 * outer->MaybeResolve(aResult);
55 * }, [holder, outer] (nsresult aRv) {
57 * outer->MaybeReject(aRv);
60 * return outer.forget();
63 * NOTE: Currently this helper class extends DETH. This is only
64 * so that it can bind to the global and receive the
65 * DisconnectFromOwner() method call. In this future the
66 * binding code should be factored out so DETH is not
67 * needed here. See bug 1456893.
69 template <typename PromiseType
>
70 class DOMMozPromiseRequestHolder final
: public DOMEventTargetHelper
{
71 MozPromiseRequestHolder
<PromiseType
> mHolder
;
73 ~DOMMozPromiseRequestHolder() = default;
75 void DisconnectFromOwner() override
{
76 mHolder
.DisconnectIfExists();
77 DOMEventTargetHelper::DisconnectFromOwner();
80 JSObject
* WrapObject(JSContext
* aCx
,
81 JS::Handle
<JSObject
*> aGivenProto
) override
{
82 // We are extending DETH to get notified when the global goes
83 // away, but this object should never actually be exposed to
85 MOZ_CRASH("illegal method");
89 explicit DOMMozPromiseRequestHolder(nsIGlobalObject
* aGlobal
)
90 : DOMEventTargetHelper(aGlobal
) {
91 MOZ_DIAGNOSTIC_ASSERT(aGlobal
);
94 operator MozPromiseRequestHolder
<PromiseType
>&() { return mHolder
; }
96 operator const MozPromiseRequestHolder
<PromiseType
>&() const {
100 void Complete() { mHolder
.Complete(); }
102 void DisconnectIfExists() { mHolder
.DisconnectIfExists(); }
104 bool Exists() const { return mHolder
.Exists(); }
106 NS_INLINE_DECL_REFCOUNTING_INHERITED(DOMMozPromiseRequestHolder
,
107 DOMEventTargetHelper
)
110 } // namespace mozilla::dom
112 #endif // mozilla_dom_DOMMozPromiseRequestHolder_h