jmar777/suspend — pull request #21 by gyson (2014-09-21 04:23:24+00:00)
Title: avoid zalgo problem and prevent promise swallowing exception

with current implementation, the callback will be called immediately when the generator function is executed completely. For example,

```js
suspend.run(function* () {
throw 'something' // or return 'something'
}, function (err) {
console.log('called first');
});
console.log('called later')
```
It has following two problem:
* [zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) problem (callback is sometimes sync, sometimes async)
```js
// callback will be called before `suspend.run` returns
suspend.run(function* () {
throw new Error();
}, callback);

// callback will be called async after `suspend.run` returns
suspend.run(function* () {
yield setTimeout(suspend.resume(), 10);
throw new Error('');
}, callback);

// therefore, it will release zalgo problem.
// about zalgo, please read following link
// http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony
```
* promise will swallow exception
```js
// without callback
suspend.run(function* () {
yield Promise.reject(new Error()); // this error will be swallowed by the promise!
});

// with callback
suspend.run(function* () {
yield Promise.resolve('something');
}, function () {
throw new Error(); // this error will be swallowed by the promise!
});

// because `promise.then` is used to get value from the promise and
// `promise.then` will create a new Promise. If there is exception within
// generator function or callback function, the created promise will swallow
// the exception, which is not what we expected.
```
A simple solution would be defer the callback or exception to next tick (use `process.nextTick` or `setImmediate`)