AsyncGenerator.js (2010B)
1 import AwaitValue from "./AwaitValue.js"; 2 export default function AsyncGenerator(gen) { 3 var front, back; 4 5 function send(key, arg) { 6 return new Promise(function (resolve, reject) { 7 var request = { 8 key: key, 9 arg: arg, 10 resolve: resolve, 11 reject: reject, 12 next: null 13 }; 14 15 if (back) { 16 back = back.next = request; 17 } else { 18 front = back = request; 19 resume(key, arg); 20 } 21 }); 22 } 23 24 function resume(key, arg) { 25 try { 26 var result = gen[key](arg); 27 var value = result.value; 28 var wrappedAwait = value instanceof AwaitValue; 29 Promise.resolve(wrappedAwait ? value.wrapped : value).then(function (arg) { 30 if (wrappedAwait) { 31 resume(key === "return" ? "return" : "next", arg); 32 return; 33 } 34 35 settle(result.done ? "return" : "normal", arg); 36 }, function (err) { 37 resume("throw", err); 38 }); 39 } catch (err) { 40 settle("throw", err); 41 } 42 } 43 44 function settle(type, value) { 45 switch (type) { 46 case "return": 47 front.resolve({ 48 value: value, 49 done: true 50 }); 51 break; 52 53 case "throw": 54 front.reject(value); 55 break; 56 57 default: 58 front.resolve({ 59 value: value, 60 done: false 61 }); 62 break; 63 } 64 65 front = front.next; 66 67 if (front) { 68 resume(front.key, front.arg); 69 } else { 70 back = null; 71 } 72 } 73 74 this._invoke = send; 75 76 if (typeof gen["return"] !== "function") { 77 this["return"] = undefined; 78 } 79 } 80 81 AsyncGenerator.prototype[typeof Symbol === "function" && Symbol.asyncIterator || "@@asyncIterator"] = function () { 82 return this; 83 }; 84 85 AsyncGenerator.prototype.next = function (arg) { 86 return this._invoke("next", arg); 87 }; 88 89 AsyncGenerator.prototype["throw"] = function (arg) { 90 return this._invoke("throw", arg); 91 }; 92 93 AsyncGenerator.prototype["return"] = function (arg) { 94 return this._invoke("return", arg); 95 };