Blame view

node_modules/when/generator.js 2.53 KB
ce4c83ff   wxy   初始提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
  /** @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); }));