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.
105 lines
2.5 KiB
105 lines
2.5 KiB
/** @license MIT License (c) copyright 2010-2014 original author or authors */ |
|
/** @author Brian Cavalier */ |
|
/** @author John Hann */ |
|
|
|
(function(define) { 'use strict'; |
|
define(function(require) { |
|
|
|
var when = require('./when'); |
|
var slice = Array.prototype.slice; |
|
var Promise = when.Promise; |
|
var reject = Promise.reject; |
|
|
|
/** |
|
* Lift a generator to create a function that can suspend and |
|
* resume using the `yield` keyword to await promises. |
|
* @param {function} generator |
|
* @return {function} |
|
*/ |
|
function lift(generator) { |
|
return function() { |
|
return run(generator, this, arguments); |
|
}; |
|
} |
|
|
|
/** |
|
* Immediately call a generator as a promise-aware coroutine |
|
* that can suspend and resume using the `yield` keyword to |
|
* await promises. Additional arguments after the first will |
|
* be passed through to the generator. |
|
* @param {function} generator |
|
* @returns {Promise} promise for the ultimate value returned |
|
* from the generator. |
|
*/ |
|
function call(generator /*x, y, z...*/) { |
|
/*jshint validthis:true*/ |
|
return run(generator, this, slice.call(arguments, 1)); |
|
} |
|
|
|
/** |
|
* Immediately apply a generator, with the supplied args array, |
|
* as a promise-aware coroutine that can suspend and resume |
|
* using the `yield` keyword to await promises. |
|
* @param {function} generator |
|
* @param {Array} args arguments with which to initialize the generator |
|
* @returns {Promise} promise for the ultimate value returned |
|
* from the generator. |
|
*/ |
|
function apply(generator, args) { |
|
/*jshint validthis:true*/ |
|
return run(generator, this, args || []); |
|
} |
|
|
|
/** |
|
* Helper to initiate the provided generator as a coroutine |
|
* @returns {*} |
|
*/ |
|
function run(generator, thisArg, args) { |
|
return runNext(void 0, generator.apply(thisArg, args)); |
|
} |
|
|
|
function runNext(x, iterator) { |
|
try { |
|
return handle(iterator.next(x), iterator); |
|
} catch(e) { |
|
return reject(e); |
|
} |
|
} |
|
|
|
function next(x) { |
|
/*jshint validthis:true*/ |
|
return runNext(x, this); |
|
} |
|
|
|
function error(e) { |
|
/*jshint validthis:true*/ |
|
try { |
|
return handle(this.throw(e), this); |
|
} catch(e) { |
|
return reject(e); |
|
} |
|
} |
|
|
|
function handle(result, iterator) { |
|
if(result.done) { |
|
return result.value; |
|
} |
|
|
|
var h = Promise._handler(result.value); |
|
if(h.state() > 0) { |
|
return runNext(h.value, iterator); |
|
} |
|
|
|
var p = Promise._defer(); |
|
h.chain(p._handler, iterator, next, error); |
|
return p; |
|
} |
|
|
|
return { |
|
lift: lift, |
|
call: call, |
|
apply: apply |
|
}; |
|
|
|
}); |
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
|
|
|