You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
44 lines
2.0 KiB
44 lines
2.0 KiB
5 months ago
|
import { Observable } from "./Observable.js";
|
||
|
// Like Observable.prototype.map, except that the mapping function can
|
||
|
// optionally return a Promise (or be async).
|
||
|
export function asyncMap(observable, mapFn, catchFn) {
|
||
|
return new Observable(function (observer) {
|
||
|
var promiseQueue = {
|
||
|
// Normally we would initialize promiseQueue to Promise.resolve(), but
|
||
|
// in this case, for backwards compatibility, we need to be careful to
|
||
|
// invoke the first callback synchronously.
|
||
|
then: function (callback) {
|
||
|
return new Promise(function (resolve) { return resolve(callback()); });
|
||
|
},
|
||
|
};
|
||
|
function makeCallback(examiner, key) {
|
||
|
return function (arg) {
|
||
|
if (examiner) {
|
||
|
var both = function () {
|
||
|
// If the observer is closed, we don't want to continue calling the
|
||
|
// mapping function - it's result will be swallowed anyways.
|
||
|
return observer.closed ?
|
||
|
/* will be swallowed */ 0
|
||
|
: examiner(arg);
|
||
|
};
|
||
|
promiseQueue = promiseQueue.then(both, both).then(function (result) { return observer.next(result); }, function (error) { return observer.error(error); });
|
||
|
}
|
||
|
else {
|
||
|
observer[key](arg);
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
var handler = {
|
||
|
next: makeCallback(mapFn, "next"),
|
||
|
error: makeCallback(catchFn, "error"),
|
||
|
complete: function () {
|
||
|
// no need to reassign `promiseQueue`, after `observer.complete`,
|
||
|
// the observer will be closed and short-circuit everything anyways
|
||
|
/*promiseQueue = */ promiseQueue.then(function () { return observer.complete(); });
|
||
|
},
|
||
|
};
|
||
|
var sub = observable.subscribe(handler);
|
||
|
return function () { return sub.unsubscribe(); };
|
||
|
});
|
||
|
}
|
||
|
//# sourceMappingURL=asyncMap.js.map
|