| @@ -0,0 +1,33 | |||
|
|
1 | import { Observable } from "./Observable"; | |
|
|
2 | import { IDestroyable } from "./interfaces"; | |
|
|
3 | import { argumentNotNull } from "./safe"; | |
|
|
4 | ||
|
|
5 | type Handler<T> = (x: T) => void; | |
|
|
6 | ||
|
|
7 | export class ObservableValue<T> extends Observable<T> { | |
|
|
8 | private _value: T; | |
|
|
9 | ||
|
|
10 | constructor(initial: T) { | |
|
|
11 | super(); | |
|
|
12 | this._value = initial; | |
|
|
13 | } | |
|
|
14 | ||
|
|
15 | getValue() { | |
|
|
16 | return this._value; | |
|
|
17 | } | |
|
|
18 | ||
|
|
19 | setValue(value: T) { | |
|
|
20 | this._value = value; | |
|
|
21 | this._notifyNext(value); | |
|
|
22 | } | |
|
|
23 | ||
|
|
24 | on(next: Handler<T>, error?: Handler<any>, complete?: () => void): IDestroyable { | |
|
|
25 | argumentNotNull(next, "next"); | |
|
|
26 | try { | |
|
|
27 | next(this._value); | |
|
|
28 | } catch { | |
|
|
29 | // suppress error | |
|
|
30 | } | |
|
|
31 | return super.on(next, error, complete); | |
|
|
32 | } | |
|
|
33 | } | |
| @@ -153,7 +153,7 export function each(obj, cb, thisArg?) | |||
|
|
153 | 153 | * own properties of the source are entirely copied to the destination. |
|
|
154 | 154 | * |
|
|
155 | 155 | */ |
|
|
156 | export function mixin<T, S>(dest: T, source: S, template?: string[] | object): T & S { | |
|
|
156 | export function mixin<T extends object, S extends object>(dest: T, source: S, template?: string[] | object): T & S { | |
|
|
157 | 157 | argumentNotNull(dest, "to"); |
|
|
158 | 158 | const _res = dest as T & S; |
|
|
159 | 159 | |
| @@ -232,7 +232,6 type _AnyFn = (...args) => any; | |||
|
|
232 | 232 | |
|
|
233 | 233 | export function delegate<T, K extends keyof T>(target: T, _method: (K | _AnyFn)) { |
|
|
234 | 234 | let method; |
|
|
235 | ||
|
|
236 | 235 | if (!(_method instanceof Function)) { |
|
|
237 | 236 | argumentNotNull(target, "target"); |
|
|
238 | 237 | method = target[_method]; |
| @@ -264,75 +263,74 export function delay(timeMs: number, ct | |||
|
|
264 | 263 | } |
|
|
265 | 264 | |
|
|
266 | 265 | /** |
|
|
267 | * Для каждого элемента массива вызывает указанную функцию и сохраняет | |
|
|
268 | * возвращенное значение в массиве результатов. | |
|
|
266 | * Iterates over the specified array of items and calls the callback `cb`, if | |
|
|
267 | * the result of the callback is a promise the next item from the array will be | |
|
|
268 | * proceeded after the promise is resolved. | |
|
|
269 | 269 | * |
|
|
270 | * @remarks cb может выполняться асинхронно, при этом одновременно будет | |
|
|
271 | * только одна операция. | |
|
|
272 | * | |
|
|
273 | * @async | |
|
|
274 | 270 | */ |
|
|
275 |
export function pmap |
|
|
|
271 | export function pmap<T, T2>( | |
|
|
272 | items: ArrayLike<T> | PromiseLike<ArrayLike<T>>, | |
|
|
273 | cb: (item: T, i: number) => T2 | PromiseLike<T2> | |
|
|
274 | ): T2[] | PromiseLike<T2[]> { | |
|
|
276 | 275 | argumentNotNull(cb, "cb"); |
|
|
277 | 276 | |
|
|
278 | if (isPromise(items)) | |
|
|
277 | if (isPromise(items)) { | |
|
|
279 | 278 | return items.then(data => pmap(data, cb)); |
|
|
279 | } else { | |
|
|
280 | 280 | |
|
|
281 | 281 | if (isNull(items) || !items.length) |
|
|
282 |
return |
|
|
|
282 | return []; | |
|
|
283 | 283 | |
|
|
284 | 284 | let i = 0; |
|
|
285 |
const result = |
|
|
|
285 | const result = new Array<T2>(); | |
|
|
286 | 286 | |
|
|
287 |
|
|
|
|
288 | let r; | |
|
|
289 | let ri; | |
|
|
290 | ||
|
|
291 | function chain(x) { | |
|
|
287 | const next = () => { | |
|
|
288 | while (i < items.length) { | |
|
|
289 | const r = cb(items[i], i); | |
|
|
290 | const ri = i; | |
|
|
291 | i++; | |
|
|
292 | if (isPromise(r)) { | |
|
|
293 | return r.then(x => { | |
|
|
292 | 294 | result[ri] = x; |
|
|
293 | 295 | return next(); |
|
|
294 | } | |
|
|
295 | ||
|
|
296 | while (i < items.length) { | |
|
|
297 | r = cb(items[i], i); | |
|
|
298 | ri = i; | |
|
|
299 | i++; | |
|
|
300 | if (isPromise(r)) { | |
|
|
301 | return r.then(chain); | |
|
|
296 | }); | |
|
|
302 | 297 | } else { |
|
|
303 | 298 | result[ri] = r; |
|
|
304 | 299 | } |
|
|
305 | 300 | } |
|
|
306 | 301 | return result; |
|
|
307 | } | |
|
|
302 | }; | |
|
|
308 | 303 | |
|
|
309 | 304 | return next(); |
|
|
310 | 305 | } |
|
|
306 | } | |
|
|
311 | 307 | |
|
|
312 |
export function pfor( |
|
|
|
308 | export function pfor<T>( | |
|
|
309 | items: ArrayLike<T> | PromiseLike<ArrayLike<T>>, | |
|
|
310 | cb: (item: T, i: number) => any | |
|
|
311 | ): void | PromiseLike<void> { | |
|
|
313 | 312 | argumentNotNull(cb, "cb"); |
|
|
314 | 313 | |
|
|
315 | if (isPromise(items)) | |
|
|
316 |
return items.then(data => |
|
|
|
317 | return pmap(data, cb); | |
|
|
318 | }); | |
|
|
319 | ||
|
|
314 | if (isPromise(items)) { | |
|
|
315 | return items.then(data => pfor(data, cb)); | |
|
|
316 | } else { | |
|
|
320 | 317 | if (isNull(items) || !items.length) |
|
|
321 |
return |
|
|
|
318 | return; | |
|
|
322 | 319 | |
|
|
323 | 320 | let i = 0; |
|
|
324 | 321 | |
|
|
325 |
|
|
|
|
322 | const next = () => { | |
|
|
326 | 323 | while (i < items.length) { |
|
|
327 | 324 | const r = cb(items[i], i); |
|
|
328 | 325 | i++; |
|
|
329 | 326 | if (isPromise(r)) |
|
|
330 | 327 | return r.then(next); |
|
|
331 | 328 | } |
|
|
332 | } | |
|
|
329 | }; | |
|
|
333 | 330 | |
|
|
334 | 331 | return next(); |
|
|
335 | 332 | } |
|
|
333 | } | |
|
|
336 | 334 | |
|
|
337 | 335 | export function first<T>(sequence: ArrayLike<T>): T; |
|
|
338 | 336 | export function first<T>(sequence: PromiseLike<ArrayLike<T>>): PromiseLike<T>; |
| @@ -368,13 +366,13 export function first<T>( | |||
|
|
368 | 366 | else |
|
|
369 | 367 | throw new Error("The sequence is empty"); |
|
|
370 | 368 | } else if (cb) { |
|
|
371 | cb(sequence[0]); | |
|
|
369 | return cb(sequence[0]); | |
|
|
372 | 370 | } else { |
|
|
373 | 371 | return sequence[0]; |
|
|
374 | 372 | } |
|
|
375 | 373 | } else { |
|
|
376 | 374 | if (err) |
|
|
377 | err(new Error("The sequence is required")); | |
|
|
375 | return err(new Error("The sequence is required")); | |
|
|
378 | 376 | else |
|
|
379 | 377 | throw new Error("The sequence is required"); |
|
|
380 | 378 | } |
| @@ -34,17 +34,21 export class FormatCompiler { | |||
|
|
34 | 34 | |
|
|
35 | 35 | this.pushSubst(fieldName, filedFormat); |
|
|
36 | 36 | } |
|
|
37 | ||
|
|
37 | 38 | pushSubst(fieldName: string, filedFormat: string) { |
|
|
38 | 39 | throw new Error("Method not implemented."); |
|
|
39 | 40 | } |
|
|
41 | ||
|
|
40 | 42 | readFieldFormat(scanner: FormatScanner): string { |
|
|
41 | 43 | throw new Error("Method not implemented."); |
|
|
42 | 44 | } |
|
|
45 | ||
|
|
43 | 46 | readColon(scanner: FormatScanner) { |
|
|
44 | 47 | if (!scanner.next()) |
|
|
45 | 48 | this.dieUnexpectedEnd(); |
|
|
46 | 49 | if (scanner.getTokenType() !== TokeType.Colon) |
|
|
47 | 50 | return false; |
|
|
51 | ||
|
|
48 | 52 | } |
|
|
49 | 53 | |
|
|
50 | 54 | pushText(text: string) { |
General Comments 0
You need to be logged in to leave comments.
Login now
