-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpromise.v
88 lines (75 loc) · 2.39 KB
/
promise.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
module vjs
type JSHostPromiseRejectionTracker = fn (&C.JSContext, JSValueConst, JSValueConst, bool, voidptr)
// `type` Callback JS Promise.
pub type CallbackPromise = fn (Promise) Value
// `enum` Promise State
pub enum JSPromiseStateEnum {
pending
resolved
rejected
}
fn C.JS_NewPromiseCapability(&C.JSContext, &C.JSValue) C.JSValue
fn C.JS_SetHostPromiseRejectionTracker(&C.JSRuntime, &JSHostPromiseRejectionTracker, voidptr)
fn C.js_std_promise_rejection_tracker(&C.JSContext, JSValueConst, JSValueConst, bool, voidptr)
fn C.JS_PromiseState(&C.JSContext, C.JSValue) JSPromiseStateEnum
fn C.JS_PromiseResult(&C.JSContext, C.JSValue) C.JSValue
// Promise structure.
pub struct Promise {
ctx Context
}
@[manualfree]
fn resolve_or_reject(ctx &Context, code int, any AnyValue) Value {
resolving_funcs := [2]C.JSValue{}
mut result_funcs := [2]C.JSValue{}
result_funcs[code] = ctx.any_to_val(any).ref
promise := ctx.c_val(C.JS_NewPromiseCapability(ctx.ref, &resolving_funcs[0]))
C.JS_Call(ctx.ref, resolving_funcs[code], promise.ref, 1, &result_funcs[code])
C.JS_FreeValue(ctx.ref, resolving_funcs[0])
C.JS_FreeValue(ctx.ref, resolving_funcs[1])
C.JS_FreeValue(ctx.ref, result_funcs[code])
return promise
}
// Create new Promise.
// Example:
// ```v
// promise := ctx.new_promise(fn [ctx](p Promise) Value {
// if err {
// return p.reject(ctx.js_error(message: 'rejected'))
// }
// return p.resolve(ctx.js_string('resolved'))
// })
//
// value := promise.await()
// println(value)
// ```
pub fn (ctx &Context) new_promise(cb CallbackPromise) Value {
return cb(Promise{ctx})
}
// Same as new_promise, but without callback.
pub fn (ctx &Context) js_promise() Promise {
return Promise{
ctx: ctx
}
}
// Promise resolve
pub fn (p Promise) resolve(any AnyValue) Value {
return resolve_or_reject(p.ctx, 0, any)
}
// Promise reject
pub fn (p Promise) reject(any AnyValue) Value {
return resolve_or_reject(p.ctx, 1, any)
}
// Promise rejection tracker (default true)
pub fn (rt Runtime) promise_rejection_tracker() {
C.JS_SetHostPromiseRejectionTracker(rt.ref, &C.js_std_promise_rejection_tracker, C.NULL)
}
// Get Promise State
pub fn (ctx &Context) promise_state(val Value) Value {
state := C.JS_PromiseState(ctx.ref, val.ref)
return ctx.js_string(state.str())
}
// Get Promise Result
pub fn (ctx &Context) promise_result(val Value) Value {
res := ctx.c_val(C.JS_PromiseResult(ctx.ref, val.ref))
return res
}