Skip to content

Instantly share code, notes, and snippets.

View mattpodwysocki's full-sized avatar

Matthew Podwysocki mattpodwysocki

View GitHub Profile

Iterables, AsyncIterables, Observables, Oh My!

I know there is a lot of confusion around Observables, Iterables, AsyncIterables and AsyncObservables. Let's try to break this down and the reasons for each.

Pull versus Push Collections

When it comes to collections, you have two ways of thinking about collections, push versus pull. With pull, the consumer is in control of when you get the items, but with push, you get the values when the producer is ready.

Pull Based Collections

<Project Sdk="MSBuild.Sdk.Extras/2.0.54">
<PropertyGroup>
<OutputType>Library</OutputType>
<RootNamespace>Microsoft.Azure.NotificationHubs.Client</RootNamespace>
<AssemblyName>Microsoft.Azure.NotificationHubs.Client</AssemblyName>
<!-- Target both iOS and Android -->
<TargetFrameworks>Xamarin.iOS10;MonoAndroid80;netstandard2.0</TargetFrameworks>
<Product>$(AssemblyName) ($(TargetFramework))</Product>
using Foundation;
using WindowsAzure.Messaging.NotificationHubs;
namespace Microsoft.Azure.NotificationHubs
{
public partial class NotificationHub
{
private static readonly NotificationHubMessageDelegate _notificationHubMessageDelegate;
static NotificationHub()

The Interactive Extensions for JavaScript (IxJS)

The Interactive Extensions for JavaScript (IxJS) is a set of methods on top of Iteratable and AsyncIterable serving as a standard library for both. Much like its push-based counterpart, the Interactive Extensions for JavaScript unifies the programming model around pull-based collections, either synchronous in the case of Iterable or asynchronous with AsyncIterable.

Iterable

Starting in ES6, the Symbol.iterator method was introduced to allow for iteration over collections such as Array, Map, Set and even ``Generator. IxJS introduces a number of creation factories and operators that operate on these Iterable` collections lazily. Each factory can be imported from `'ix/iterable'` and operators from `'ix/iterable/operators'` such as the following creating an iterable via `of` and then transforming each item using the `map` operator. You c

#import <Foundation/Foundation.h>
@class MSNotificationHub;
@class MSInstallation;
@protocol MSInstallationEnrichmentDelegate <NSObject>
@optional
- (void)notificationHub:(MSNotificationHub *)notificationHub willEnrichInstallation:(MSInstallation *)installation;
import { AsyncIterableX } from '../asynciterablex';
import { OperatorAsyncFunction } from '../../interfaces';
import { wrapWithAbort } from './withabort';
import { throwIfAborted } from '../../aborterror';
import { identity } from '../../util/identity';
// eslint-disable-next-line @typescript-eslint/no-empty-function
const NEVER_PROMISE = new Promise(() => {});
type MergeResult<T> = { value: T; index: number };
import { identity, identityAsync } from '../util/identity';
import { wrapWithAbort } from './operators/withabort';
// eslint-disable-next-line @typescript-eslint/no-empty-function
const NEVER_PROMISE = new Promise(() => {});
type MergeResult<T> = { value: T; index: number };
function wrapPromiseWithIndex<T>(promise: Promise<T>, index: number) {
return promise.then(value => ({ value, index })) as Promise<MergeResult<T>>;
import { identityAsync } from '../util/identity';
import { wrapWithAbort } from './operators/withabort';
import { throwIfAborted } from '../aborterror';
/**
* The options for calculating an average.
*
* @export
* @interface AverageOptions
* @template T The type of elements in the source sequence.
import { AsyncIterableX } from './asynciterablex';
import { throwIfAborted, AbortError } from '../aborterror';
export class NeverAsyncIterable extends AsyncIterableX<never> {
constructor() {
super();
}
async *[Symbol.asyncIterator](signal?: AbortSignal) {
throwIfAborted(signal);
import { AbortSignal } from '../../abortsignal';
import { AsyncIterableX } from '../asynciterablex';
import { MonoTypeOperatorAsyncFunction } from '../../interfaces';
import { wrapWithAbort } from './withabort';
import { AbortError } from '../../aborterror';
async function forEach<T>(
source: AsyncIterable<T>,
fn: (item: T, signal?: AbortSignal) => void | Promise<void>,
signal?: AbortSignal