-
-
Notifications
You must be signed in to change notification settings - Fork 185
Expand file tree
/
Copy pathAwait.ts
More file actions
59 lines (55 loc) · 2.31 KB
/
Await.ts
File metadata and controls
59 lines (55 loc) · 2.31 KB
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
// The following is a translation of the TypeScript async awaiter which uses generators and yields.
// For Lua we use coroutines instead.
//
// Source:
//
// var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
// function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
// return new (P || (P = Promise))(function (resolve, reject) {
// function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
// function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
// function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
// step((generator = generator.apply(thisArg, _arguments || [])).next());
// });
// };
//
import { __TS__Promise } from "./Promise";
// eslint-disable-next-line @typescript-eslint/promise-function-async
export function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) {
return new Promise((resolve, reject) => {
let resolved = false;
const asyncCoroutine = coroutine.create(generator);
// eslint-disable-next-line @typescript-eslint/promise-function-async
function adopt(value: unknown) {
return value instanceof __TS__Promise ? value : Promise.resolve(value);
}
function fulfilled(value: unknown) {
const [success, resultOrError] = coroutine.resume(asyncCoroutine, value);
if (success) {
step(resultOrError);
} else {
reject(resultOrError);
}
}
function step(result: unknown) {
if (resolved) return;
if (coroutine.status(asyncCoroutine) === "dead") {
resolve(result);
} else {
adopt(result).then(fulfilled, reject);
}
}
const [success, resultOrError] = coroutine.resume(asyncCoroutine, (v: unknown) => {
resolved = true;
adopt(v).then(resolve, reject);
});
if (success) {
step(resultOrError);
} else {
reject(resultOrError);
}
});
}
export function __TS__Await(this: void, thing: unknown) {
return coroutine.yield(thing);
}