最近对async/await
的实现产生了兴趣,看了下babel
的转译,调用了regeneratorRuntime
的几个函数。
打开源码看了一下午,有很多东西不是很理解。
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return setTimeout(function (v) {
return console.log(v);
}, 1000);
case 2:
case "end":
return _context.stop();
}
}
以上代码我目前的理解是执行了个状态监听器,await
后的函数执行完毕后会改变_context.next
,然后结束这个状态机。
但在 console 中,执行while(true){}
页面几乎是秒卡的。
求指教!
以上运行环境为 chrome console 。
async function log (v) {
await setTimeout(v => console.log(v), 1000)
}
babel =>
"use strict";
var log = function () {
var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee(v) {
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return setTimeout(function (v) {
return console.log(v);
}, 1000);
case 2:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return function log(_x) {
return _ref.apply(this, arguments);
};
}();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
1
lujjjh 2016-12-16 21:24:49 +08:00
因为有 return ,所以循环只会跑一次……而且 setTimeout() 返回的并不是一个 Promise ,用 await 怪怪的吧。
while (1) 其实是给 loop 里有 await 的用的,比如 for (let i = 10; i--; ) await Promise.resolve(); 如果可以直接 goto 到某个 label 的话,就不需要这个 while (1) 了。 |
2
lujjjh 2016-12-16 21:34:29 +08:00
我也没研究过 Babel transpile 出来的代码,好像只要 await 在控制流程语句或者 try...catch block 里就没法在 switch 里一路 fallthrough 下去,需要跳转到隔开的某个状态里。
|
3
2zH OP @lujjjh
async 内部 return 的好像就是一个 promise: function _asyncToGenerator(fn) { return function() { var gen = fn.apply(this, arguments); return new Promise(function(resolve, reject) {... }); }; } var log = function () { var _ref = _asyncToGenerator(...); return function log(_x) { return _ref.apply(this, arguments); }; }(); 之前没有注意到 while 里面那个 return ,下一步往哪里挖有了许多头绪,谢谢指教! |