Angular 的服务工作者使用 yield
进行异步控制流。然后将每个生成器函数传递给此函数:
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
这与巴别塔的_asyncToGenerator
非常相似
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) {
return step("next", value);
}, function (err) {
return step("throw", err);
});
}
}
return step("next");
});
};
}
将yield
用于异步控制流有什么好处?我认为yield
和await
之间在 caniuse.com 浏览器支持方面绝对没有区别。
换句话说
使用这个有什么意义:
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
__awaiter(this, void 0, void 0, function* () {
const foo = yield 3;
const bar = yield new Promise(resolve => resolve(7));
const baz = bar * foo;
console.log(baz);
});
取而代之的是:
(async function () {
const foo = await 3;
const bar = await new Promise(resolve => resolve('7'));
const baz = bar * foo;
console.log(baz);
})();
鉴于此:
- ES6 发生器支持
- 异步功能支持(绝对没有区别(
,承诺旨在执行一次性任务,其中生成器旨在重复任务,直到任务列表用尽。 如果列表永远不会用尽,那么生成器将继续,就好像它是一个非基于时间的(setInterval()
(迭代器,可以在操作之间暂停。
这可以在生成器的 MDN 示例中看到:
function* idMaker() {
var index = 0;
while (true)
yield index++;
}
var gen = idMaker(); // "Generator { }"
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
如果while
循环生成了一个 Promise 对象,它将类似于您提供的源示例。然后,生成器将根据需要重复生成 Promise 对象,从而为异步操作生成控制流。
示例中提供的逻辑只是在需要时履行 Promise 协定,从而进一步推动此方案。