Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81160 views
1
"use strict";
2
module.exports = function(Promise,
3
apiRejection,
4
INTERNAL,
5
tryConvertToPromise) {
6
var errors = require("./errors.js");
7
var TypeError = errors.TypeError;
8
var util = require("./util.js");
9
var errorObj = util.errorObj;
10
var tryCatch = util.tryCatch;
11
var yieldHandlers = [];
12
13
function promiseFromYieldHandler(value, yieldHandlers, traceParent) {
14
for (var i = 0; i < yieldHandlers.length; ++i) {
15
traceParent._pushContext();
16
var result = tryCatch(yieldHandlers[i])(value);
17
traceParent._popContext();
18
if (result === errorObj) {
19
traceParent._pushContext();
20
var ret = Promise.reject(errorObj.e);
21
traceParent._popContext();
22
return ret;
23
}
24
var maybePromise = tryConvertToPromise(result, traceParent);
25
if (maybePromise instanceof Promise) return maybePromise;
26
}
27
return null;
28
}
29
30
function PromiseSpawn(generatorFunction, receiver, yieldHandler, stack) {
31
var promise = this._promise = new Promise(INTERNAL);
32
promise._captureStackTrace();
33
this._stack = stack;
34
this._generatorFunction = generatorFunction;
35
this._receiver = receiver;
36
this._generator = undefined;
37
this._yieldHandlers = typeof yieldHandler === "function"
38
? [yieldHandler].concat(yieldHandlers)
39
: yieldHandlers;
40
}
41
42
PromiseSpawn.prototype.promise = function () {
43
return this._promise;
44
};
45
46
PromiseSpawn.prototype._run = function () {
47
this._generator = this._generatorFunction.call(this._receiver);
48
this._receiver =
49
this._generatorFunction = undefined;
50
this._next(undefined);
51
};
52
53
PromiseSpawn.prototype._continue = function (result) {
54
if (result === errorObj) {
55
return this._promise._rejectCallback(result.e, false, true);
56
}
57
58
var value = result.value;
59
if (result.done === true) {
60
this._promise._resolveCallback(value);
61
} else {
62
var maybePromise = tryConvertToPromise(value, this._promise);
63
if (!(maybePromise instanceof Promise)) {
64
maybePromise =
65
promiseFromYieldHandler(maybePromise,
66
this._yieldHandlers,
67
this._promise);
68
if (maybePromise === null) {
69
this._throw(
70
new TypeError(
71
"A value %s was yielded that could not be treated as a promise\u000a\u000a See http://goo.gl/4Y4pDk\u000a\u000a".replace("%s", value) +
72
"From coroutine:\u000a" +
73
this._stack.split("\n").slice(1, -7).join("\n")
74
)
75
);
76
return;
77
}
78
}
79
maybePromise._then(
80
this._next,
81
this._throw,
82
undefined,
83
this,
84
null
85
);
86
}
87
};
88
89
PromiseSpawn.prototype._throw = function (reason) {
90
this._promise._attachExtraTrace(reason);
91
this._promise._pushContext();
92
var result = tryCatch(this._generator["throw"])
93
.call(this._generator, reason);
94
this._promise._popContext();
95
this._continue(result);
96
};
97
98
PromiseSpawn.prototype._next = function (value) {
99
this._promise._pushContext();
100
var result = tryCatch(this._generator.next).call(this._generator, value);
101
this._promise._popContext();
102
this._continue(result);
103
};
104
105
Promise.coroutine = function (generatorFunction, options) {
106
if (typeof generatorFunction !== "function") {
107
throw new TypeError("generatorFunction must be a function\u000a\u000a See http://goo.gl/6Vqhm0\u000a");
108
}
109
var yieldHandler = Object(options).yieldHandler;
110
var PromiseSpawn$ = PromiseSpawn;
111
var stack = new Error().stack;
112
return function () {
113
var generator = generatorFunction.apply(this, arguments);
114
var spawn = new PromiseSpawn$(undefined, undefined, yieldHandler,
115
stack);
116
spawn._generator = generator;
117
spawn._next(undefined);
118
return spawn.promise();
119
};
120
};
121
122
Promise.coroutine.addYieldHandler = function(fn) {
123
if (typeof fn !== "function") throw new TypeError("fn must be a function\u000a\u000a See http://goo.gl/916lJJ\u000a");
124
yieldHandlers.push(fn);
125
};
126
127
Promise.spawn = function (generatorFunction) {
128
if (typeof generatorFunction !== "function") {
129
return apiRejection("generatorFunction must be a function\u000a\u000a See http://goo.gl/6Vqhm0\u000a");
130
}
131
var spawn = new PromiseSpawn(generatorFunction, this);
132
var ret = spawn.promise();
133
spawn._run(Promise.spawn);
134
return ret;
135
};
136
};
137
138