cujojs / most

Ultra-high performance reactive programming
MIT License
3.49k stars 231 forks source link

Unexpected raising error sequence #404

Open xareelee opened 7 years ago

xareelee commented 7 years ago

I try to use Most.js instead of RxJS.

The following code obtains an unexpected result:

import * as Most from 'most';

function asyncReject() {
  return new Promise((_, reject) =>
    reject(new Error('Error getting asyncReject'))
  );
}

function asyncRawReject() {
  return Promise.reject('Error getting asyncRawReject');
}

function asyncError() {
  return new Promise(() => {
    throw new Error('Error getting asyncError');
  });
}

function asyncRawError() {
  return new Promise(() => {
    /* eslint-disable */
    throw 'Error getting asyncRawError';
    /* eslint-enable */
  });
}

function asyncReturnError() {
  return Promise.resolve(new Error('Error getting asyncReturnError'));
}

// We will execute those Promises in the sequence
const promiseExecutors = [
  asyncReject,
  asyncRawReject,
  asyncError,
  asyncRawError,
  asyncReturnError
]

const streams = promiseExecutors.reduce((collection, executor) => {
  const promise = executor();
  const stream = Most.fromPromise(promise)
    .flatMap(x => {
      if (x instanceof Error) {
        return Most.throwError(x);
      }
      return Most.of(x);
    });
  return collection.concat(stream);
}, []);

const combined = Most.combineArray((...values) => [ ...values ], streams);

combined.subscribe({
  next: (x) => console.log('[next]:', x),
  error: (err) => console.log('[error]:', err.message ? err.message : err),
  complete: () => console.log('[complete]'),
})

// Results:
// [error]: Error getting asyncReturnError        // => should be the last
// [error]: Error getting asyncReject
// [error]: Error getting asyncRawReject
// [error]: Error getting asyncError
// [error]: Error getting asyncRawError

// Expected (the same as the sequence in the executors):
// [error]: Error getting asyncReject
// [error]: Error getting asyncRawReject
// [error]: Error getting asyncError
// [error]: Error getting asyncRawError
// [error]: Error getting asyncReturnError

I'll get asyncReturnError first as unexpected. It seems that the error events from Promise in Most.js are not synchronous.

When I use RxJS, I can get the errors in the same sequence as the executors, but not when using Most.js.

How can I fix this if it is not a bug?

davidchase commented 7 years ago

hi @xareelee,

When i tested your issue in the webpackbin, I noticed that the asyncReturnError was being resolved rather than rejected is that expected ?

If i change it to reject similar to your other error functions you get your expected results http://www.webpackbin.com/V1_lYi5Yf

xareelee commented 7 years ago

hi @davidchase ,

This test case is obtained from graphql-js. The error is expected to be resolved.

I'm trying to replace the Promise-based execute() with Observable-based (like most.js), and this is the one failed test case.