bluebird
Version:
Full featured Promises/A+ implementation with exceptionally good performance
95 lines (86 loc) • 3.25 kB
JavaScript
/**
* Copyright (c) 2013 Petka Antonov
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:</p>
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
"use strict";
var Promise = require("./get_promise.js").get();
var errors = require( "./errors.js" );
var TypeError = errors.TypeError;
var ensureNotHandled = errors.ensureNotHandled;
var util = require("./util.js");
var errorObj = util.errorObj;
var tryCatch1 = util.tryCatch1;
function PromiseSpawn( generatorFunction, receiver, caller ) {
this._resolver = Promise.pending( caller );
this._generatorFunction = generatorFunction;
this._receiver = receiver;
this._generator = void 0;
}
PromiseSpawn.prototype.promise = function PromiseSpawn$promise() {
return this._resolver.promise;
};
PromiseSpawn.prototype._run = function PromiseSpawn$_run() {
this._generator = this._generatorFunction.call( this._receiver );
this._receiver =
this._generatorFunction = void 0;
this._next( void 0 );
};
PromiseSpawn.prototype._continue = function PromiseSpawn$_continue( result ) {
if( result === errorObj ) {
this._generator = void 0;
this._resolver.reject( result.e );
return;
}
var value = result.value;
if( result.done === true ) {
this._generator = void 0;
this._resolver.fulfill( value );
}
else {
var maybePromise = Promise._cast( value, PromiseSpawn$_continue );
if( !( maybePromise instanceof Promise ) ) {
this._throw( new TypeError(
"A value was yielded that could not be treated as a promise"
) );
return;
}
maybePromise._then(
this._next,
this._throw,
void 0,
this,
null,
void 0
);
}
};
PromiseSpawn.prototype._throw = function PromiseSpawn$_throw( reason ) {
ensureNotHandled( reason );
this.promise()._attachExtraTrace( reason );
this._continue(
tryCatch1( this._generator["throw"], this._generator, reason )
);
};
PromiseSpawn.prototype._next = function PromiseSpawn$_next( value ) {
this._continue(
tryCatch1( this._generator.next, this._generator, value )
);
};
module.exports = PromiseSpawn;