regeneratorRuntime 运行环境配置

注意710行与711行有做变更,代码来源于babel官网
https://babeljs.io/docs/en/learn
https://babeljs.io/repl

  1. /**
  2. * Copyright (c) 2014-present, Facebook, Inc.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. var runtime = (function (exports) {
  8. "use strict";
  9. var Op = Object.prototype;
  10. var hasOwn = Op.hasOwnProperty;
  11. var undefined; // More compressible than void 0.
  12. var $Symbol = typeof Symbol === "function" ? Symbol : {};
  13. var iteratorSymbol = $Symbol.iterator || "@@iterator";
  14. var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
  15. var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
  16. function wrap(innerFn, outerFn, self, tryLocsList) {
  17. // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
  18. var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
  19. var generator = Object.create(protoGenerator.prototype);
  20. var context = new Context(tryLocsList || []);
  21. // The ._invoke method unifies the implementations of the .next,
  22. // .throw, and .return methods.
  23. generator._invoke = makeInvokeMethod(innerFn, self, context);
  24. return generator;
  25. }
  26. exports.wrap = wrap;
  27. // Try/catch helper to minimize deoptimizations. Returns a completion
  28. // record like context.tryEntries[i].completion. This interface could
  29. // have been (and was previously) designed to take a closure to be
  30. // invoked without arguments, but in all the cases we care about we
  31. // already have an existing method we want to call, so there's no need
  32. // to create a new function object. We can even get away with assuming
  33. // the method takes exactly one argument, since that happens to be true
  34. // in every case, so we don't have to touch the arguments object. The
  35. // only additional allocation required is the completion record, which
  36. // has a stable shape and so hopefully should be cheap to allocate.
  37. function tryCatch(fn, obj, arg) {
  38. try {
  39. return { type: "normal", arg: fn.call(obj, arg) };
  40. } catch (err) {
  41. return { type: "throw", arg: err };
  42. }
  43. }
  44. var GenStateSuspendedStart = "suspendedStart";
  45. var GenStateSuspendedYield = "suspendedYield";
  46. var GenStateExecuting = "executing";
  47. var GenStateCompleted = "completed";
  48. // Returning this object from the innerFn has the same effect as
  49. // breaking out of the dispatch switch statement.
  50. var ContinueSentinel = {};
  51. // Dummy constructor functions that we use as the .constructor and
  52. // .constructor.prototype properties for functions that return Generator
  53. // objects. For full spec compliance, you may wish to configure your
  54. // minifier not to mangle the names of these two functions.
  55. function Generator() {}
  56. function GeneratorFunction() {}
  57. function GeneratorFunctionPrototype() {}
  58. // This is a polyfill for %IteratorPrototype% for environments that
  59. // don't natively support it.
  60. var IteratorPrototype = {};
  61. IteratorPrototype[iteratorSymbol] = function () {
  62. return this;
  63. };
  64. var getProto = Object.getPrototypeOf;
  65. var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  66. if (NativeIteratorPrototype &&
  67. NativeIteratorPrototype !== Op &&
  68. hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
  69. // This environment has a native %IteratorPrototype%; use it instead
  70. // of the polyfill.
  71. IteratorPrototype = NativeIteratorPrototype;
  72. }
  73. var Gp = GeneratorFunctionPrototype.prototype =
  74. Generator.prototype = Object.create(IteratorPrototype);
  75. GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
  76. GeneratorFunctionPrototype.constructor = GeneratorFunction;
  77. GeneratorFunctionPrototype[toStringTagSymbol] =
  78. GeneratorFunction.displayName = "GeneratorFunction";
  79. // Helper for defining the .next, .throw, and .return methods of the
  80. // Iterator interface in terms of a single ._invoke method.
  81. function defineIteratorMethods(prototype) {
  82. ["next", "throw", "return"].forEach(function(method) {
  83. prototype[method] = function(arg) {
  84. return this._invoke(method, arg);
  85. };
  86. });
  87. }
  88. exports.isGeneratorFunction = function(genFun) {
  89. var ctor = typeof genFun === "function" && genFun.constructor;
  90. return ctor
  91. ? ctor === GeneratorFunction ||
  92. // For the native GeneratorFunction constructor, the best we can
  93. // do is to check its .name property.
  94. (ctor.displayName || ctor.name) === "GeneratorFunction"
  95. : false;
  96. };
  97. exports.mark = function(genFun) {
  98. if (Object.setPrototypeOf) {
  99. Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
  100. } else {
  101. genFun.__proto__ = GeneratorFunctionPrototype;
  102. if (!(toStringTagSymbol in genFun)) {
  103. genFun[toStringTagSymbol] = "GeneratorFunction";
  104. }
  105. }
  106. genFun.prototype = Object.create(Gp);
  107. return genFun;
  108. };
  109. // Within the body of any async function, `await x` is transformed to
  110. // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
  111. // `hasOwn.call(value, "__await")` to determine if the yielded value is
  112. // meant to be awaited.
  113. exports.awrap = function(arg) {
  114. return { __await: arg };
  115. };
  116. function AsyncIterator(generator) {
  117. function invoke(method, arg, resolve, reject) {
  118. var record = tryCatch(generator[method], generator, arg);
  119. if (record.type === "throw") {
  120. reject(record.arg);
  121. } else {
  122. var result = record.arg;
  123. var value = result.value;
  124. if (value &&
  125. typeof value === "object" &&
  126. hasOwn.call(value, "__await")) {
  127. return Promise.resolve(value.__await).then(function(value) {
  128. invoke("next", value, resolve, reject);
  129. }, function(err) {
  130. invoke("throw", err, resolve, reject);
  131. });
  132. }
  133. return Promise.resolve(value).then(function(unwrapped) {
  134. // When a yielded Promise is resolved, its final value becomes
  135. // the .value of the Promise<{value,done}> result for the
  136. // current iteration.
  137. result.value = unwrapped;
  138. resolve(result);
  139. }, function(error) {
  140. // If a rejected Promise was yielded, throw the rejection back
  141. // into the async generator function so it can be handled there.
  142. return invoke("throw", error, resolve, reject);
  143. });
  144. }
  145. }
  146. var previousPromise;
  147. function enqueue(method, arg) {
  148. function callInvokeWithMethodAndArg() {
  149. return new Promise(function(resolve, reject) {
  150. invoke(method, arg, resolve, reject);
  151. });
  152. }
  153. return previousPromise =
  154. // If enqueue has been called before, then we want to wait until
  155. // all previous Promises have been resolved before calling invoke,
  156. // so that results are always delivered in the correct order. If
  157. // enqueue has not been called before, then it is important to
  158. // call invoke immediately, without waiting on a callback to fire,
  159. // so that the async generator function has the opportunity to do
  160. // any necessary setup in a predictable way. This predictability
  161. // is why the Promise constructor synchronously invokes its
  162. // executor callback, and why async functions synchronously
  163. // execute code before the first await. Since we implement simple
  164. // async functions in terms of async generators, it is especially
  165. // important to get this right, even though it requires care.
  166. previousPromise ? previousPromise.then(
  167. callInvokeWithMethodAndArg,
  168. // Avoid propagating failures to Promises returned by later
  169. // invocations of the iterator.
  170. callInvokeWithMethodAndArg
  171. ) : callInvokeWithMethodAndArg();
  172. }
  173. // Define the unified helper method that is used to implement .next,
  174. // .throw, and .return (see defineIteratorMethods).
  175. this._invoke = enqueue;
  176. }
  177. defineIteratorMethods(AsyncIterator.prototype);
  178. AsyncIterator.prototype[asyncIteratorSymbol] = function () {
  179. return this;
  180. };
  181. exports.AsyncIterator = AsyncIterator;
  182. // Note that simple async functions are implemented on top of
  183. // AsyncIterator objects; they just return a Promise for the value of
  184. // the final result produced by the iterator.
  185. exports.async = function(innerFn, outerFn, self, tryLocsList) {
  186. var iter = new AsyncIterator(
  187. wrap(innerFn, outerFn, self, tryLocsList)
  188. );
  189. return exports.isGeneratorFunction(outerFn)
  190. ? iter // If outerFn is a generator, return the full iterator.
  191. : iter.next().then(function(result) {
  192. return result.done ? result.value : iter.next();
  193. });
  194. };
  195. function makeInvokeMethod(innerFn, self, context) {
  196. var state = GenStateSuspendedStart;
  197. return function invoke(method, arg) {
  198. if (state === GenStateExecuting) {
  199. throw new Error("Generator is already running");
  200. }
  201. if (state === GenStateCompleted) {
  202. if (method === "throw") {
  203. throw arg;
  204. }
  205. // Be forgiving, per 25.3.3.3.3 of the spec:
  206. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
  207. return doneResult();
  208. }
  209. context.method = method;
  210. context.arg = arg;
  211. while (true) {
  212. var delegate = context.delegate;
  213. if (delegate) {
  214. var delegateResult = maybeInvokeDelegate(delegate, context);
  215. if (delegateResult) {
  216. if (delegateResult === ContinueSentinel) continue;
  217. return delegateResult;
  218. }
  219. }
  220. if (context.method === "next") {
  221. // Setting context._sent for legacy support of Babel's
  222. // function.sent implementation.
  223. context.sent = context._sent = context.arg;
  224. } else if (context.method === "throw") {
  225. if (state === GenStateSuspendedStart) {
  226. state = GenStateCompleted;
  227. throw context.arg;
  228. }
  229. context.dispatchException(context.arg);
  230. } else if (context.method === "return") {
  231. context.abrupt("return", context.arg);
  232. }
  233. state = GenStateExecuting;
  234. var record = tryCatch(innerFn, self, context);
  235. if (record.type === "normal") {
  236. // If an exception is thrown from innerFn, we leave state ===
  237. // GenStateExecuting and loop back for another invocation.
  238. state = context.done
  239. ? GenStateCompleted
  240. : GenStateSuspendedYield;
  241. if (record.arg === ContinueSentinel) {
  242. continue;
  243. }
  244. return {
  245. value: record.arg,
  246. done: context.done
  247. };
  248. } else if (record.type === "throw") {
  249. state = GenStateCompleted;
  250. // Dispatch the exception by looping back around to the
  251. // context.dispatchException(context.arg) call above.
  252. context.method = "throw";
  253. context.arg = record.arg;
  254. }
  255. }
  256. };
  257. }
  258. // Call delegate.iterator[context.method](context.arg) and handle the
  259. // result, either by returning a { value, done } result from the
  260. // delegate iterator, or by modifying context.method and context.arg,
  261. // setting context.delegate to null, and returning the ContinueSentinel.
  262. function maybeInvokeDelegate(delegate, context) {
  263. var method = delegate.iterator[context.method];
  264. if (method === undefined) {
  265. // A .throw or .return when the delegate iterator has no .throw
  266. // method always terminates the yield* loop.
  267. context.delegate = null;
  268. if (context.method === "throw") {
  269. // Note: ["return"] must be used for ES3 parsing compatibility.
  270. if (delegate.iterator["return"]) {
  271. // If the delegate iterator has a return method, give it a
  272. // chance to clean up.
  273. context.method = "return";
  274. context.arg = undefined;
  275. maybeInvokeDelegate(delegate, context);
  276. if (context.method === "throw") {
  277. // If maybeInvokeDelegate(context) changed context.method from
  278. // "return" to "throw", let that override the TypeError below.
  279. return ContinueSentinel;
  280. }
  281. }
  282. context.method = "throw";
  283. context.arg = new TypeError(
  284. "The iterator does not provide a 'throw' method");
  285. }
  286. return ContinueSentinel;
  287. }
  288. var record = tryCatch(method, delegate.iterator, context.arg);
  289. if (record.type === "throw") {
  290. context.method = "throw";
  291. context.arg = record.arg;
  292. context.delegate = null;
  293. return ContinueSentinel;
  294. }
  295. var info = record.arg;
  296. if (! info) {
  297. context.method = "throw";
  298. context.arg = new TypeError("iterator result is not an object");
  299. context.delegate = null;
  300. return ContinueSentinel;
  301. }
  302. if (info.done) {
  303. // Assign the result of the finished delegate to the temporary
  304. // variable specified by delegate.resultName (see delegateYield).
  305. context[delegate.resultName] = info.value;
  306. // Resume execution at the desired location (see delegateYield).
  307. context.next = delegate.nextLoc;
  308. // If context.method was "throw" but the delegate handled the
  309. // exception, let the outer generator proceed normally. If
  310. // context.method was "next", forget context.arg since it has been
  311. // "consumed" by the delegate iterator. If context.method was
  312. // "return", allow the original .return call to continue in the
  313. // outer generator.
  314. if (context.method !== "return") {
  315. context.method = "next";
  316. context.arg = undefined;
  317. }
  318. } else {
  319. // Re-yield the result returned by the delegate method.
  320. return info;
  321. }
  322. // The delegate iterator is finished, so forget it and continue with
  323. // the outer generator.
  324. context.delegate = null;
  325. return ContinueSentinel;
  326. }
  327. // Define Generator.prototype.{next,throw,return} in terms of the
  328. // unified ._invoke helper method.
  329. defineIteratorMethods(Gp);
  330. Gp[toStringTagSymbol] = "Generator";
  331. // A Generator should always return itself as the iterator object when the
  332. // @@iterator function is called on it. Some browsers' implementations of the
  333. // iterator prototype chain incorrectly implement this, causing the Generator
  334. // object to not be returned from this call. This ensures that doesn't happen.
  335. // See https://github.com/facebook/regenerator/issues/274 for more details.
  336. Gp[iteratorSymbol] = function() {
  337. return this;
  338. };
  339. Gp.toString = function() {
  340. return "[object Generator]";
  341. };
  342. function pushTryEntry(locs) {
  343. var entry = { tryLoc: locs[0] };
  344. if (1 in locs) {
  345. entry.catchLoc = locs[1];
  346. }
  347. if (2 in locs) {
  348. entry.finallyLoc = locs[2];
  349. entry.afterLoc = locs[3];
  350. }
  351. this.tryEntries.push(entry);
  352. }
  353. function resetTryEntry(entry) {
  354. var record = entry.completion || {};
  355. record.type = "normal";
  356. delete record.arg;
  357. entry.completion = record;
  358. }
  359. function Context(tryLocsList) {
  360. // The root entry object (effectively a try statement without a catch
  361. // or a finally block) gives us a place to store values thrown from
  362. // locations where there is no enclosing try statement.
  363. this.tryEntries = [{ tryLoc: "root" }];
  364. tryLocsList.forEach(pushTryEntry, this);
  365. this.reset(true);
  366. }
  367. exports.keys = function(object) {
  368. var keys = [];
  369. for (var key in object) {
  370. keys.push(key);
  371. }
  372. keys.reverse();
  373. // Rather than returning an object with a next method, we keep
  374. // things simple and return the next function itself.
  375. return function next() {
  376. while (keys.length) {
  377. var key = keys.pop();
  378. if (key in object) {
  379. next.value = key;
  380. next.done = false;
  381. return next;
  382. }
  383. }
  384. // To avoid creating an additional object, we just hang the .value
  385. // and .done properties off the next function object itself. This
  386. // also ensures that the minifier will not anonymize the function.
  387. next.done = true;
  388. return next;
  389. };
  390. };
  391. function values(iterable) {
  392. if (iterable) {
  393. var iteratorMethod = iterable[iteratorSymbol];
  394. if (iteratorMethod) {
  395. return iteratorMethod.call(iterable);
  396. }
  397. if (typeof iterable.next === "function") {
  398. return iterable;
  399. }
  400. if (!isNaN(iterable.length)) {
  401. var i = -1, next = function next() {
  402. while (++i < iterable.length) {
  403. if (hasOwn.call(iterable, i)) {
  404. next.value = iterable[i];
  405. next.done = false;
  406. return next;
  407. }
  408. }
  409. next.value = undefined;
  410. next.done = true;
  411. return next;
  412. };
  413. return next.next = next;
  414. }
  415. }
  416. // Return an iterator with no values.
  417. return { next: doneResult };
  418. }
  419. exports.values = values;
  420. function doneResult() {
  421. return { value: undefined, done: true };
  422. }
  423. Context.prototype = {
  424. constructor: Context,
  425. reset: function(skipTempReset) {
  426. this.prev = 0;
  427. this.next = 0;
  428. // Resetting context._sent for legacy support of Babel's
  429. // function.sent implementation.
  430. this.sent = this._sent = undefined;
  431. this.done = false;
  432. this.delegate = null;
  433. this.method = "next";
  434. this.arg = undefined;
  435. this.tryEntries.forEach(resetTryEntry);
  436. if (!skipTempReset) {
  437. for (var name in this) {
  438. // Not sure about the optimal order of these conditions:
  439. if (name.charAt(0) === "t" &&
  440. hasOwn.call(this, name) &&
  441. !isNaN(+name.slice(1))) {
  442. this[name] = undefined;
  443. }
  444. }
  445. }
  446. },
  447. stop: function() {
  448. this.done = true;
  449. var rootEntry = this.tryEntries[0];
  450. var rootRecord = rootEntry.completion;
  451. if (rootRecord.type === "throw") {
  452. throw rootRecord.arg;
  453. }
  454. return this.rval;
  455. },
  456. dispatchException: function(exception) {
  457. if (this.done) {
  458. throw exception;
  459. }
  460. var context = this;
  461. function handle(loc, caught) {
  462. record.type = "throw";
  463. record.arg = exception;
  464. context.next = loc;
  465. if (caught) {
  466. // If the dispatched exception was caught by a catch block,
  467. // then let that catch block handle the exception normally.
  468. context.method = "next";
  469. context.arg = undefined;
  470. }
  471. return !! caught;
  472. }
  473. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  474. var entry = this.tryEntries[i];
  475. var record = entry.completion;
  476. if (entry.tryLoc === "root") {
  477. // Exception thrown outside of any try block that could handle
  478. // it, so set the completion value of the entire function to
  479. // throw the exception.
  480. return handle("end");
  481. }
  482. if (entry.tryLoc <= this.prev) {
  483. var hasCatch = hasOwn.call(entry, "catchLoc");
  484. var hasFinally = hasOwn.call(entry, "finallyLoc");
  485. if (hasCatch && hasFinally) {
  486. if (this.prev < entry.catchLoc) {
  487. return handle(entry.catchLoc, true);
  488. } else if (this.prev < entry.finallyLoc) {
  489. return handle(entry.finallyLoc);
  490. }
  491. } else if (hasCatch) {
  492. if (this.prev < entry.catchLoc) {
  493. return handle(entry.catchLoc, true);
  494. }
  495. } else if (hasFinally) {
  496. if (this.prev < entry.finallyLoc) {
  497. return handle(entry.finallyLoc);
  498. }
  499. } else {
  500. throw new Error("try statement without catch or finally");
  501. }
  502. }
  503. }
  504. },
  505. abrupt: function(type, arg) {
  506. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  507. var entry = this.tryEntries[i];
  508. if (entry.tryLoc <= this.prev &&
  509. hasOwn.call(entry, "finallyLoc") &&
  510. this.prev < entry.finallyLoc) {
  511. var finallyEntry = entry;
  512. break;
  513. }
  514. }
  515. if (finallyEntry &&
  516. (type === "break" ||
  517. type === "continue") &&
  518. finallyEntry.tryLoc <= arg &&
  519. arg <= finallyEntry.finallyLoc) {
  520. // Ignore the finally entry if control is not jumping to a
  521. // location outside the try/catch block.
  522. finallyEntry = null;
  523. }
  524. var record = finallyEntry ? finallyEntry.completion : {};
  525. record.type = type;
  526. record.arg = arg;
  527. if (finallyEntry) {
  528. this.method = "next";
  529. this.next = finallyEntry.finallyLoc;
  530. return ContinueSentinel;
  531. }
  532. return this.complete(record);
  533. },
  534. complete: function(record, afterLoc) {
  535. if (record.type === "throw") {
  536. throw record.arg;
  537. }
  538. if (record.type === "break" ||
  539. record.type === "continue") {
  540. this.next = record.arg;
  541. } else if (record.type === "return") {
  542. this.rval = this.arg = record.arg;
  543. this.method = "return";
  544. this.next = "end";
  545. } else if (record.type === "normal" && afterLoc) {
  546. this.next = afterLoc;
  547. }
  548. return ContinueSentinel;
  549. },
  550. finish: function(finallyLoc) {
  551. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  552. var entry = this.tryEntries[i];
  553. if (entry.finallyLoc === finallyLoc) {
  554. this.complete(entry.completion, entry.afterLoc);
  555. resetTryEntry(entry);
  556. return ContinueSentinel;
  557. }
  558. }
  559. },
  560. "catch": function(tryLoc) {
  561. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  562. var entry = this.tryEntries[i];
  563. if (entry.tryLoc === tryLoc) {
  564. var record = entry.completion;
  565. if (record.type === "throw") {
  566. var thrown = record.arg;
  567. resetTryEntry(entry);
  568. }
  569. return thrown;
  570. }
  571. }
  572. // The context.catch method must only be called with a location
  573. // argument that corresponds to a known catch block.
  574. throw new Error("illegal catch attempt");
  575. },
  576. delegateYield: function(iterable, resultName, nextLoc) {
  577. this.delegate = {
  578. iterator: values(iterable),
  579. resultName: resultName,
  580. nextLoc: nextLoc
  581. };
  582. if (this.method === "next") {
  583. // Deliberately forget the last sent value so that we don't
  584. // accidentally pass it on to the delegate.
  585. this.arg = undefined;
  586. }
  587. return ContinueSentinel;
  588. }
  589. };
  590. // Regardless of whether this script is executing as a CommonJS module
  591. // or not, return the runtime object so that we can declare the variable
  592. // regeneratorRuntime in the outer scope, which allows this module to be
  593. // injected easily by `bin/regenerator --include-runtime script.js`.
  594. return exports;
  595. }(
  596. // If this script is executing as a CommonJS module, use module.exports
  597. // as the regeneratorRuntime namespace. Otherwise create a new empty
  598. // object. Either way, the resulting object will be used to initialize
  599. // the regeneratorRuntime variable at the top of this file.
  600. /* true ? module.exports : undefined */
  601. { exports: {} }
  602. ));
  603. try {
  604. regeneratorRuntime = runtime;
  605. } catch (accidentalStrictMode) {
  606. // This module should not be running in strict mode, so the above
  607. // assignment should always work unless something is misconfigured. Just
  608. // in case runtime.js accidentally runs in strict mode, we can escape
  609. // strict mode using a global Function call. This could conceivably fail
  610. // if a Content Security Policy forbids using Function, but in that case
  611. // the proper solution is to fix the accidental strict mode problem. If
  612. // you've misconfigured your bundler to force strict mode and applied a
  613. // CSP to forbid Function, and you're not willing to fix either of those
  614. // problems, please detail your unique predicament in a GitHub issue.
  615. Function("r", "regeneratorRuntime = r")(runtime);
  616. }

bable编译前的代码

  1. function * demo (){
  2. console.log('1')
  3. var a = yield new Promise(function(resolve, reject){
  4. console.log('2');
  5. setTimeout(()=>{
  6. console.log('3');
  7. resolve(1);
  8. }, 3000);
  9. });
  10. console.log('4');
  11. var b = yield Promise.resolve(a + 1);
  12. console.log('5');
  13. var c = yield Promise.resolve(b + 1);
  14. return c;
  15. }
  16. function co(generator) {
  17. var gen = generator();
  18. function nextFunc(arg) {
  19. console.log('arg', arg);
  20. var next = gen.next(arg);
  21. if (!next.done) {
  22. next.value.then(function(data){
  23. console.log('data',data);
  24. nextFunc(data);
  25. });
  26. } else if (next.value) {
  27. console.log('return',next.value)
  28. return next.value;
  29. }
  30. }
  31. nextFunc();
  32. }
  33. co(demo);
  34. arg undefined
  35. VM672:2 1
  36. VM672:4 2
  37. undefined
  38. VM672:6 3
  39. VM672:23 data 1
  40. VM672:19 arg 1
  41. VM672:10 4
  42. VM672:23 data 2
  43. VM672:19 arg 2
  44. VM672:12 5
  45. VM672:23 data 3
  46. VM672:19 arg 3
  47. VM672:27 return 3

babel编译后的代码

  1. "use strict";
  2. var _marked =
  3. /*#__PURE__*/
  4. regeneratorRuntime.mark(demo);
  5. function demo() {
  6. var a, b, c;
  7. return regeneratorRuntime.wrap(function demo$(_context) {
  8. while (1) {
  9. switch (_context.prev = _context.next) {
  10. case 0:
  11. _context.next = 2;
  12. return Promise.resolve(1);
  13. case 2:
  14. a = _context.sent;
  15. _context.next = 5;
  16. return Promise.resolve(a + 1);
  17. case 5:
  18. b = _context.sent;
  19. _context.next = 8;
  20. return Promise.resolve(b + 1);
  21. case 8:
  22. c = _context.sent;
  23. return _context.abrupt("return", c);
  24. case 10:
  25. case "end":
  26. return _context.stop();
  27. }
  28. }
  29. }, _marked);
  30. }
  31. function co(generator) {
  32. var gen = generator();
  33. function nextFunc(arg) {
  34. console.log('arg', arg);
  35. var next = gen.next(arg);
  36. if (!next.done) {
  37. next.value.then(function (data) {
  38. console.log('data', data);
  39. nextFunc(data);
  40. });
  41. } else if (next.value) {
  42. console.log('return', next.value);
  43. return next.value;
  44. }
  45. }
  46. nextFunc();
  47. }
  48. co(demo);

学习过的后的理解

1.创建3个构造函数,Generator,GeneratorFunction,GeneratorFunctionPrototype
2.首先将数组的Symbol.iterator的拿出来给上面的三个构造函数使用
3.var _marked = regeneratorRuntime.mark(demo); 方法将next与throw,return方法添加到demo里面,是demo的类型变成Generator类型
4.co是一个函数执行器,当完成第一个操作的时候,执行next方法执行第二个方法
5.demo是一个函数分配器,指定下一步执行什么处理

  1. var regeneratorRuntime = (function (exports) {
  2. "use strict";
  3. function Generator() { };
  4. function GeneratorFunctionPrototype() { };
  5. function GeneratorFunction() { };
  6. var Op = Object.prototype;
  7. var $Symbol = typeof Symbol === 'function' ? Symbol : {};
  8. var iteratorSymbol = $Symbol.iterator || "@@iterator";
  9. var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
  10. var hasOwn = Object.hasOwnProperty;
  11. var getProto = Object.getPrototypeOf;
  12. ;;;;;;
  13. var IteratorPrototype = {};
  14. IteratorPrototype[iteratorSymbol] = function () {
  15. return this;
  16. }
  17. function values(iterable) {
  18. if (iterable) {
  19. var iteratorMethod = iterable[iteratorSymbol];
  20. if (iteratorMethod) {
  21. return iteratorMethod.call(iterable);
  22. }
  23. }
  24. }
  25. var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  26. if (NativeIteratorPrototype && NativeIteratorPrototype !== Op &&
  27. hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
  28. ;;;;;
  29. // 将数组的 Array Iterator 给了 IteratorPrototype
  30. IteratorPrototype = NativeIteratorPrototype;
  31. }
  32. var Gp = GeneratorFunctionPrototype.prototype =
  33. Generator.prototype = Object.create(IteratorPrototype);
  34. GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
  35. GeneratorFunctionPrototype.constructor = GeneratorFunction;
  36. GeneratorFunctionPrototype[toStringTagSymbol] =
  37. GeneratorFunction.displayName = "GeneratorFunction";
  38. defineIteratorMethods(Gp);
  39. Gp[toStringTagSymbol] = "Generator";
  40. Gp[iteratorSymbol] = function () {
  41. return this;
  42. };
  43. Gp.toString = function () {
  44. return "[object Generator]";
  45. };
  46. function defineIteratorMethods(prototype) {
  47. ['next', 'throw', 'return'].forEach(function (method) {
  48. ;;;;;
  49. prototype[method] = function (arg) {
  50. ;;;;;
  51. return this._invoke(method, arg);
  52. }
  53. });
  54. }
  55. exports.mark = function (genFun) {
  56. Object.setPrototypeOf(genFun, Generator);
  57. genFun.prototype = Object.create(Gp);
  58. return genFun;
  59. }
  60. exports.wrap = function (innerFn, outerFn) {
  61. // innerFn, outerFn
  62. var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
  63. var generator = Object.create(protoGenerator.prototype);
  64. var context = new Context([]);
  65. generator._invoke = makeInvokeMethod(innerFn, self, context);
  66. return generator;
  67. }
  68. function tryCatch(fn, obj, arg) { // 公共的try catch
  69. ;;;;;;
  70. try {
  71. // arg 返回函数执行结果
  72. return { type: 'normal', arg: fn.call(obj, arg) };
  73. } catch (err) {
  74. return { type: 'throw', arg: err };
  75. }
  76. }
  77. function Context(arg) {
  78. this.arg = undefined;
  79. this.delegate = null;
  80. this.done = false;
  81. this.method = "next";
  82. this.next = 0;
  83. this.prev = 0;
  84. this.sent = undefined
  85. this.tryEntries = [];
  86. this._sent = undefined
  87. }
  88. // 一些状态值
  89. var GenStateSuspendedStart = "suspendedStart";
  90. var GenStateSuspendedYield = "suspendedYield";
  91. var GenStateExecuting = "executing";
  92. var GenStateCompleted = "completed";
  93. var ContinueSentinel = {};
  94. function makeInvokeMethod(innerFn, self, context) {
  95. var state = GenStateSuspendedStart;
  96. ;;;;;;
  97. return function invoke(method, arg) {
  98. ;;;;;;
  99. if (state === GenStateExecuting) {
  100. throw new Error("Generator is already running");
  101. }
  102. if (state === GenStateCompleted) {
  103. if (method === "throw") {
  104. throw arg;
  105. }
  106. return doneResult();
  107. }
  108. context.method = method;
  109. context.arg = arg;
  110. while (true) {
  111. state = GenStateExecuting;
  112. if (context.method === 'next') {
  113. context.sent = context._sent = context.arg;
  114. } else if (context.method === 'throw') {
  115. if (state === GenStateSuspendedStart) {
  116. state = GenStateCompleted;
  117. throw context.arg;
  118. }
  119. return {
  120. done: true,
  121. value: arg
  122. }
  123. } else if (context.method === 'return') {
  124. state = GenStateCompleted;
  125. return {
  126. done: true,
  127. value: arg
  128. }
  129. }
  130. var record = tryCatch(innerFn, self, context);
  131. state = GenStateExecuting;
  132. if (record.type === 'normal') {
  133. state = context.done
  134. ? GenStateCompleted
  135. : GenStateSuspendedYield;
  136. if (record.arg === ContinueSentinel) {
  137. continue;
  138. }
  139. return {
  140. value: record.arg,
  141. done: context.done
  142. }
  143. } else if (record.type === "throw") {
  144. state = GenStateCompleted;
  145. context.method = "throw";
  146. context.arg = record.arg;
  147. }
  148. }
  149. }
  150. }
  151. return exports;
  152. })({ exports: {} });
  153. var _marked =
  154. /*#__PURE__*/
  155. regeneratorRuntime.mark(demo);
  156. function demo() {
  157. var a, b, c;
  158. return regeneratorRuntime.wrap(function demo$(_context) {
  159. while (1) {
  160. switch (_context.prev = _context.next) {
  161. case 0:
  162. _context.next = 2;
  163. return Promise.resolve(1);
  164. case 2:
  165. a = _context.sent;
  166. _context.next = 5;
  167. return Promise.resolve(a + 1);
  168. case 5:
  169. b = _context.sent;
  170. _context.next = 8;
  171. return Promise.resolve(b + 1);
  172. case 8:
  173. c = _context.sent;
  174. return _context.abrupt("return", c);
  175. case 10:
  176. case "end":
  177. return _context.stop();
  178. }
  179. }
  180. }, _marked);
  181. }
  182. function co(generator) {
  183. var gen = generator();
  184. function nextFunc(arg) {
  185. var next = gen.next(arg);
  186. console.log('next', next);
  187. if (!next.done) {
  188. next.value.then(function (data) {
  189. nextFunc(data);
  190. });
  191. } else if (next.value) {
  192. console.log('return', next.value);
  193. return next.value;
  194. }
  195. }
  196. nextFunc();
  197. }
  198. co(demo);
  1. var runtime = (function (exports) {
  2. "use strict";
  3. debugger
  4. var Op = Object.prototype;
  5. var hasOwn = Object.hasOwnProperty;
  6. var undefined;
  7. var $Symbol = typeof Symbol === 'function' ? Symbol : {};
  8. // 同步的迭代器
  9. var iteratorSymbol = $Symbol.iterator || "@@iterator";
  10. // 异步的迭代器
  11. var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
  12. // [object TagName]
  13. var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
  14. // 一些状态值
  15. var GenStateSuspendedStart = "suspendedStart";
  16. var GenStateSuspendedYield = "suspendedYield";
  17. var GenStateExecuting = "executing";
  18. var GenStateCompleted = "completed";
  19. var ContinueSentinel = {};
  20. var IteratorPrototype = {};
  21. IteratorPrototype[iteratorSymbol] = function () {
  22. // 此方法相当于一个展位符,在后面的语句里被修改
  23. // IteratorPrototype此对象会具备数组Array的Symbol.iterator方法
  24. debugger
  25. return this;
  26. }
  27. var getProto = Object.getPrototypeOf;
  28. // 获取数组的原型的原型 是一个实例没有prototype方法
  29. // getProto(getProto(values([]))) return { Symbol(Symbol.iterator): fn ,__proto__: Object }
  30. // 返回了一个object的实例
  31. var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  32. if (NativeIteratorPrototype && NativeIteratorPrototype !== Op &&
  33. hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
  34. debugger
  35. // 将数组的 Array Iterator 给了 IteratorPrototype
  36. IteratorPrototype = NativeIteratorPrototype;
  37. }
  38. /*
  39. 使他们都具备Symbol.iterator接口
  40. 注意Gp是一个Object的实例, GeneratorFunctionPrototype原型, Generator的原型
  41. */
  42. var Gp = GeneratorFunctionPrototype.prototype =
  43. Generator.prototype = Object.create(IteratorPrototype);
  44. GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
  45. GeneratorFunctionPrototype.constructor = GeneratorFunction;
  46. GeneratorFunctionPrototype[toStringTagSymbol] =
  47. GeneratorFunction.displayName = "GeneratorFunction";
  48. defineIteratorMethods(AsyncIterator.prototype); // 添加默认方法next,return,throw
  49. AsyncIterator.prototype[asyncIteratorSymbol] = function () {
  50. debugger
  51. return this;
  52. }
  53. defineIteratorMethods(Gp); // 添加默认方法next,return,throw
  54. Gp[toStringTagSymbol] = "Generator";
  55. Gp[iteratorSymbol] = function () {
  56. debugger
  57. return this;
  58. };
  59. Gp.toString = function () {
  60. debugger
  61. return "[object Generator]";
  62. };
  63. Context.prototype = {
  64. constructor: Context,
  65. reset: function (skipTempReset) { // (#6)
  66. debugger;
  67. this.prev = 0;
  68. this.next = 0;
  69. this.sent = this._sent = undefined;
  70. this.done = false;
  71. this.delegate = null;
  72. this.method = 'next';
  73. this.arg = undefined;
  74. this.tryEntries.forEach(resetTryEntry);
  75. if (!skipTempReset) {
  76. for (var name in this) {
  77. if (name.charAt(0) === 't' &&
  78. hasOwn.call(this, name) &&
  79. !isNaN(+name.slice(1))
  80. ) {
  81. this[name] = undefined;
  82. }
  83. }
  84. }
  85. },
  86. stop: function () {
  87. debugger
  88. this.done = true;
  89. var rootEntry = this.tryEntries[0];
  90. var rootRecord = rootEntry.completion;
  91. if (rootRecord.type === 'throw') {
  92. throw rootRecord.arg;
  93. }
  94. return this.rval;
  95. },
  96. dispatchException: function (exception) {
  97. debugger
  98. if (this.done) {
  99. throw exception;
  100. }
  101. var context = this;
  102. function handle(loc, caught) {
  103. debugger
  104. record.type = "throw";
  105. record.arg = exception;
  106. context.next = loc;
  107. if (caught) {
  108. context.method = "next";
  109. context.arg = undefined;
  110. }
  111. return !!caught;
  112. }
  113. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  114. var entry = this.tryEntries[i];
  115. var record = entry.completion;
  116. if (entry.tryLoc === "root") {
  117. return handle("end");
  118. }
  119. if (entry.tryLoc <= this.prev) {
  120. var hasCatch = hasOwn.call(entry, "catchLoc");
  121. var hasFinally = hasOwn.call(entry, "finallyLoc");
  122. if (hasCatch && hasFinally) {
  123. if (this.prev < entry.catchLoc) {
  124. return handle(entry.catchLoc, true);
  125. } else if (this.prev < entry.finallyLoc) {
  126. return handle(entry.finallyLoc);
  127. }
  128. } else if (hasCatch) {
  129. if (this.prev < entry.catchLoc) {
  130. return handle(entry.catchLoc, true);
  131. }
  132. } else if (hasFinally) {
  133. if (this.prev < entry.finallyLoc) {
  134. return handle(entry.finallyLoc);
  135. }
  136. } else {
  137. throw new Error("try statement without catch or finally");
  138. }
  139. }
  140. }
  141. },
  142. abrupt: function (type, arg) {
  143. debugger
  144. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  145. var entry = this.tryEntries[i];
  146. if (entry.tryLoc <= this.prev &&
  147. hasOwn.call(entry, "finallyLoc") &&
  148. this.prev < entry.finallyLoc) {
  149. var finallyEntry = entry;
  150. break;
  151. }
  152. }
  153. if (finallyEntry &&
  154. (type === "break" ||
  155. type === "continue") &&
  156. finallyEntry.tryLoc <= arg &&
  157. arg <= finallyEntry.finallyLoc) {
  158. // Ignore the finally entry if control is not jumping to a
  159. // location outside the try/catch block.
  160. finallyEntry = null;
  161. }
  162. var record = finallyEntry ? finallyEntry.completion : {};
  163. record.type = type;
  164. record.arg = arg;
  165. if (finallyEntry) {
  166. this.method = "next";
  167. this.next = finallyEntry.finallyLoc;
  168. return ContinueSentinel;
  169. }
  170. return this.complete(record);
  171. },
  172. complete: function (record, afterLoc) {
  173. debugger
  174. if (record.type === "throw") {
  175. throw record.arg;
  176. }
  177. if (record.type === "break" ||
  178. record.type === "continue") {
  179. this.next = record.arg;
  180. } else if (record.type === "return") {
  181. this.rval = this.arg = record.arg;
  182. this.method = "return";
  183. this.next = "end";
  184. } else if (record.type === "normal" && afterLoc) {
  185. this.next = afterLoc;
  186. }
  187. return ContinueSentinel;
  188. },
  189. finish: function (finallyLoc) {
  190. debugger
  191. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  192. var entry = this.tryEntries[i];
  193. if (entry.finallyLoc === finallyLoc) {
  194. this.complete(entry.completion, entry.afterLoc);
  195. resetTryEntry(entry);
  196. return ContinueSentinel;
  197. }
  198. }
  199. },
  200. catch: function (tryLoc) {
  201. debugger
  202. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  203. var entry = this.tryEntries[i];
  204. if (entry.tryLoc === tryLoc) {
  205. var record = entry.completion;
  206. if (record.type === "throw") {
  207. var thrown = record.arg;
  208. resetTryEntry(entry);
  209. }
  210. return thrown;
  211. }
  212. }
  213. // The context.catch method must only be called with a location
  214. // argument that corresponds to a known catch block.
  215. throw new Error("illegal catch attempt");
  216. },
  217. delegateYield: function (iterable, resultName, nextLoc) {
  218. debugger
  219. this.delegate = {
  220. iterator: values(iterable),
  221. resultName: resultName,
  222. nextLoc: nextLoc
  223. };
  224. if (this.method === "next") {
  225. // Deliberately forget the last sent value so that we don't
  226. // accidentally pass it on to the delegate.
  227. this.arg = undefined;
  228. }
  229. return ContinueSentinel;
  230. }
  231. }
  232. function AsyncIterator(generator) { // 异步的迭代器
  233. debugger
  234. function invoke(method, arg, resolve, reject) {
  235. debugger
  236. var record = tryCatch(generator[method], generator, arg);
  237. if (record.type === 'throw') {
  238. reject(record.arg);
  239. } else {
  240. var result = record.arg;
  241. var value = result.value;
  242. if (value && typeof value === "object" &&
  243. hasOwn.call(value, "__await")
  244. ) {
  245. return Promise.resolve(value.__await).then(function (value) {
  246. invoke("next", value, resolve, reject);
  247. }, function (err) {
  248. invoke("throw", err, resolve, reject);
  249. });
  250. }
  251. return Promise.resolve(value).then(function (unwraooed) {
  252. result.value = unwrapped;
  253. resolve(result);
  254. }, function (error) {
  255. return invoke("throw", error, resolve, reject);
  256. });
  257. }
  258. }
  259. var previousPromise;
  260. function enqueue(method, arg) {
  261. debugger
  262. function callInvokeWithMethodAndArg() {
  263. debugger
  264. return new Promise(function (resolve, reject) {
  265. invoke(method, arg, resolve, reject);
  266. });
  267. }
  268. return previousPromise = previousPromise ? previousPromise.then(
  269. callInvokeWithMethodAndArg,
  270. callInvokeWithMethodAndArg
  271. ) : callInvokeWithMethodAndArg();
  272. }
  273. this._invoke = enqueue;
  274. }
  275. function makeInvokeMethod(innerFn, self, context) { // (#8)// exports.wrap 里面调用
  276. debugger
  277. var state = GenStateSuspendedStart;
  278. return function invoke(method, arg) {
  279. debugger
  280. if (state === GenStateExecuting) {
  281. throw new Error("Generator is already running")
  282. }
  283. if (state === GenStateCompleted) {
  284. if (method === 'throw') {
  285. throw arg;
  286. }
  287. return doneResult();
  288. }
  289. context.method = method;
  290. context.arg = arg;
  291. while (true) {
  292. var delegate = context.delegate;
  293. if (delegate) {
  294. var delegateResult = maybeInvokeDelegate(delegate, context);
  295. if (delegateResult) {
  296. if (delegateResult === ContinueSentinel) continue;
  297. return delegateResult;
  298. }
  299. }
  300. if (context.method === 'next') {
  301. context.sent = context._sent = context.arg;
  302. } else if (context.method === 'throw') {
  303. if (state === GenStateSuspendedStart) {
  304. state = GenStateCompleted;
  305. throw context.arg;
  306. }
  307. context.dispatchException(context.arg);
  308. } else if (context.method === 'return') {
  309. context.abrupt("return", context.arg);
  310. }
  311. state = GenStateExecuting;
  312. var record = tryCatch(innerFn, self, context);
  313. if (record.type === 'normal') {
  314. state = context.done
  315. ? GenStateCompleted
  316. : GenStateSuspendedYield;
  317. if (record.arg === ContinueSentinel) {
  318. continue;
  319. }
  320. return {
  321. value: record.arg,
  322. done: context.done
  323. }
  324. } else if (record.type === "throw") {
  325. state = GenStateCompleted;
  326. context.method = "throw";
  327. context.arg = record.arg;
  328. }
  329. }
  330. };
  331. }
  332. function maybeInvokeDelegate(delegate, context) {// makeInvokeMethod 有调用
  333. debugger
  334. var method = delegate.iterator[context.method];
  335. if (method === undefined) {
  336. context.delegate = null;
  337. if (context.method === 'throw') {
  338. if (delegate.iterator["return"]) {
  339. context.method = "return";
  340. context.arg = undefined;
  341. maybeInvokeDelegate(delegate, context);
  342. if (context.method === 'throw') {
  343. return ContinueSentinel;
  344. }
  345. }
  346. context.method = "throw";
  347. context.arg = new TypeError(
  348. "The iterator does not provide a 'throw' method");
  349. }
  350. return ContinueSentinel;
  351. }
  352. var record = tryCatch(method, delegate.iterator, context.arg);
  353. if (record.type === 'throw') {
  354. context.method = 'throw';
  355. context.arg = record.arg;
  356. context.delegate = null;
  357. return ContinueSentinel;
  358. }
  359. var info = record.arg;
  360. if (!info) {
  361. context.method = "throw";
  362. context.arg = new TypeError("iterator result is not an object");
  363. context.delegate = null;
  364. return ContinueSentinel;
  365. }
  366. if (info.done) {
  367. context[delegate.resultName] = info.value;
  368. context.next = delegate.nextLoc;
  369. if (context.method !== 'return') {
  370. context.method = "next";
  371. context.arg = undefined;
  372. }
  373. } else {
  374. return info;
  375. }
  376. context.delegate = null;
  377. return ContinueSentinel;
  378. }
  379. function values(iterable) { // (#1)
  380. debugger
  381. if (iterable) {
  382. /*
  383. var a = [];
  384. a.push('1');
  385. a['iterator'] = { a: 1 };
  386. console.log(a); // ['1', 'iterator': { a: 1} ]
  387. console.log(a.length); // 1
  388. a.push('2');
  389. console.log(a.length); // 2
  390. */
  391. // 数组默认具备Iterator接口
  392. var iteratorMethod = iterable[iteratorSymbol];
  393. if (iteratorMethod) {
  394. // 返回一个 Array Iterator { __proto__: Array Iterator }
  395. return iteratorMethod.call(iterable);
  396. }
  397. if (typeof iterable.next === 'function') {
  398. return iterable;
  399. }
  400. if (!isNaN(iterable.length)) {
  401. var i = -1, next = function next() {
  402. while (++i < iterable.length) {
  403. if (hasOwn.call(iterable, i)) {
  404. next.value = iterable[i];
  405. next.done = false;
  406. return next;
  407. }
  408. }
  409. next.value = undefined;
  410. next.done = true;
  411. return next;
  412. }
  413. return next.next = next;
  414. }
  415. }
  416. return { next: doneResult };
  417. }
  418. function pushTryEntry(locs) { // Context方法在使用
  419. debugger
  420. var entry = { tryLoc: locs[0] };
  421. if (1 in locs) {
  422. entry.catchLoc = locs[1];
  423. }
  424. if (2 in locs) {
  425. entry.finallyLoc = locs[2];
  426. entry.afterLoc = locs[3];
  427. }
  428. this.tryEntries.push(entry);
  429. }
  430. function resetTryEntry(entry) { // (#7) // Context对象的reset方法在使用
  431. debugger
  432. var record = entry.completion || {};
  433. record.type = "normal";
  434. delete record.arg;
  435. entry.completion = record;
  436. }
  437. function Context(tryLocsList) { // (#5)
  438. debugger
  439. this.tryEntries = [{ tryLoc: "root" }];
  440. tryLocsList.forEach(pushTryEntry, this);
  441. this.reset(true);
  442. }
  443. function doneResult() {
  444. debugger
  445. return { value: undefined, done: true };
  446. }
  447. function defineIteratorMethods(prototype) { //(#2)
  448. debugger
  449. ['next', 'throw', 'return'].forEach(function (method) {
  450. debugger
  451. prototype[method] = function (arg) {
  452. debugger
  453. return this._invoke(method, arg);
  454. }
  455. });
  456. }
  457. function tryCatch(fn, obj, arg) { // 公共的try catch
  458. debugger
  459. try {
  460. // arg 返回函数执行结果
  461. return { type: 'normal', arg: fn.call(obj, arg) };
  462. } catch (err) {
  463. return { type: 'throw', arg: err };
  464. }
  465. }
  466. function Generator() {
  467. console.log('Generator')
  468. };
  469. function GeneratorFunction() {
  470. console.log('GeneratorFunction')
  471. };
  472. function GeneratorFunctionPrototype() {
  473. console.log('GeneratorFunctionPrototype')
  474. };
  475. function wrap(innerFn, outerFn, self, tryLocsList) { // (#4)
  476. // 执行
  477. debugger
  478. var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
  479. var generator = Object.create(protoGenerator.prototype);
  480. var context = new Context(tryLocsList || []);
  481. generator._invoke = makeInvokeMethod(innerFn, self, context);
  482. return generator;
  483. }
  484. function mark(genFun) {// (#3) // 声明这个函数是一个Generator函数
  485. debugger
  486. // 改变函数的原型的类型,以及他的原型链
  487. /* 最初的时候
  488. genFun:function
  489. genFun.prototype:object { contructor: function(){ 这个是它本身 } }
  490. genFun.__proto__:function 指向function.prototype
  491. */
  492. if (Object.setPrototypeOf) {
  493. // 改变他的原型链,就可以使用原型链上的方法
  494. Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
  495. } else {
  496. // 改变他的原型链,就可以使用原型链上的方法
  497. genFun.__proto__ = GeneratorFunctionPrototype;
  498. if (!(toStringTagSymbol in genFun)) {
  499. genFun[toStringTagSymbol] = "GeneratorFunction";
  500. }
  501. }
  502. // 改变他的原型类型,可以使用它的原型的方法
  503. genFun.prototype = Object.create(Gp);
  504. /* 最初的时候
  505. genFun:function
  506. genFun.prototype: Generator
  507. genFun.__proto__: GeneratorFunctionPrototype
  508. */
  509. return genFun;
  510. }
  511. exports.wrap = wrap;
  512. exports.isGeneratorFunction = function (genFun) {
  513. debugger
  514. var ctor = typeof genFun === 'function' && genFun.constructor;
  515. return ctor
  516. ? ctor === GeneratorFunction ||
  517. (ctor.displayName || ctor.name) === "GeneratorFunction"
  518. : false;;
  519. }
  520. exports.mark = mark;
  521. exports.awrap = function (arg) {
  522. debugger
  523. return { __await: arg };
  524. }
  525. exports.AsyncIterator = AsyncIterator;
  526. exports.async = function (innerFn, outerFn, self, tryLocsList) {
  527. debugger
  528. iter = new AsyncIterator(
  529. wrap(innerFn, outerFn, self, tryLocsList)
  530. );
  531. return exports.isGeneratorFunction(outerFn)
  532. ? iter :
  533. iter.next().then(function (result) {
  534. debugger
  535. return result.done ? result.value : iter.next();
  536. });
  537. };
  538. exports.keys = function (object) {
  539. debugger
  540. var keys = [];
  541. for (var key in object) {
  542. keys.push(key);
  543. }
  544. keys.reverse();
  545. return function next() {
  546. while (keys.length) {
  547. var key = keys.pop();
  548. if (key in object) {
  549. next.value = key;
  550. next.done = false;
  551. return next;
  552. }
  553. }
  554. next.done = true;
  555. return next;
  556. }
  557. }
  558. exports.values = values;
  559. return exports;
  560. })({ exports: {} });
  561. try {
  562. regeneratorRuntime = runtime;
  563. } catch (accidentalStrictMode) {
  564. // 严格模式下可能会有异常出现
  565. Function("r", "regeneratorRuntime = r")(runtime);
  566. }
  567. var _marked =
  568. /*#__PURE__*/
  569. regeneratorRuntime.mark(demo);
  570. function demo() {
  571. debugger
  572. var a, b, c;
  573. return regeneratorRuntime.wrap(function demo$(_context) {
  574. debugger
  575. while (1) {
  576. switch (_context.prev = _context.next) {
  577. case 0:
  578. _context.next = 2;
  579. return Promise.resolve(1);
  580. case 2:
  581. a = _context.sent;
  582. _context.next = 5;
  583. return Promise.resolve(a + 1);
  584. case 5:
  585. b = _context.sent;
  586. _context.next = 8;
  587. return Promise.resolve(b + 1);
  588. case 8:
  589. c = _context.sent;
  590. return _context.abrupt("return", c);
  591. case 10:
  592. case "end":
  593. return _context.stop();
  594. }
  595. }
  596. }, _marked);
  597. }
  598. function co(generator) {
  599. debugger
  600. var gen = generator();
  601. function nextFunc(arg) {
  602. debugger
  603. console.log('arg', arg);
  604. var next = gen.next(arg);
  605. if (!next.done) {
  606. next.value.then(function (data) {
  607. console.log('data', data);
  608. nextFunc(data);
  609. });
  610. } else if (next.value) {
  611. console.log('return', next.value);
  612. return next.value;
  613. }
  614. }
  615. nextFunc();
  616. }
  617. co(demo);