ES6之异步流程的前世今生(下)
generator/co
讲之前先来看一个es6的东西
function* foo() {
yield 1;
yield 2;
yield 3;
return console.log(4)
}
var it = foo();
it.next();
it.next();
it.next();
it.next(); //4function *doSomething() {
console.log(‘start’)
yield
console.log(‘finish’)
}
var func1 = doSomething();
func1.next();
func1.next();
function* getStorckPrice(stock) {
while (true) {
yield Math.random() * 100;
}
}
var priceGenerator = getStockPrice(‘IBM’);
var limitPrice = 15;
var price = 100;
while (price > limitPrice) {
price = priceGenerator.next().value;
console.log( `this generator return ${price}` );
}
console.log( `buying at ${price}` );
generator 原理
我们 Google 了一下,这个是 facebook 下的一个工具:regeneratorRuntime ,用于编译 ES6 的 generator 函数。
我们进行下载
然后创建一个generator, js文件
执行以下代码
以下称为编译简单版, 这个肯定是不能跑的,因为有我们遇到的 regeneratorRuntime。wap.
主要用到迭代器的 Iterator.next 的调用。
regenerator --include-runtime geberator.js > generator-es5.js
或者可以得出一个编译后 700 多行的点东西,我们抽离除主要逻辑
还有
接下来我们看一下 mark 函数
里面 GeneratorFunctionPrototype 和 Gp 变量, 我们查看对应的代码:
function Generator(){}
function GeneratorFunction(){}
它们的作用就是维持关系链,跟原生的保持一致。例如:
我们将 next、throw、return 函数怪哉gp对象上。
所以当我们 hell = hllGenerator() 的时候,执行的其实是 wrap 函数,wrap 函数返回一个 generator, generator 对象,她有 outerFn、outerFn. 其实就是genFun.prototype, getFun.prototype 是一个控对象,原型上面有next()方法。hell.next() 的时候,其实是 generator._invoke = makeInvokeMethod(innerFn, self, context); 这里的 innerFun 就是wrap 包裹的函数。hiGenerator接下来我们看一下 makeInvokeMethod 函数里面的主要功能是 invoke 函数 根据不同的context状态来进行相应的操作。hi.next()=>record=> innerFn.call(self, context)=>abrupt,我们 record 对象。这个对象有 complete 方法。
语法上generator,有两个特征:
function 关键字与函数名之前有一个星号.
函数体内部使用yield关键字,定义不同的内部状态。
generator 本意是 iterator 生成器,函数运行到yield时退出,并保留上下文。控制函数的执行过程,手工暂停和恢复代码执行. generator 的弊端是没有执行器,本身也不是为流程控制而生的,所以出现了co co 是 tj 大神开发的库 github地址
async/await
async 函数的执行过程
1)await帮我们处理了 promise,要么返回兑现的值,要么抛出异常;
2)await在等待 promise 兑现的同时,整个 async 函数会挂起,promise 兑现后再重新执行接下来的代码。
async/await 原理
我们用 babel 编译下,async/await转换出什么。
yeah,瞬间好长一串,不过莫慌。我们先理性(慌张)分析一波。 它先定义了 三个个函数 asyncGeneratorStep、 _asyncToGenerator、tell wow, 我们发现就tell这个函数我们看的懂,而且很熟悉, Promsie(不熟悉的先去补补上面的知识),ok, 在看剩下来的两个函数。我们大概分析下,asyncGeneratorStep 这个应该是根据不同的状态我们要怎么处理(做具体的事情)。 _asyncToGenerator、tell 这个函数呢,则是将传入的函数变量做分配处理,起分配作用。(不做具体事情)。
接来下我们看看 a定义的这个主函数。整个采用了switch模式,根据不同的状态,分发事件。
根据以上原理 我们可以写一个简易版的
generator()生成它的控制器。接着调用 handle 函数,并传入 interator.next(), 接着遇到 yield 生成器再次挂起,把结果(promsie)传给 handle,接着在执行 interatorValue.then(),将异步请求的值传给 interator.next(), 再次执行生成器。最后当(iteratorResult.done)为true时,退出。
await 的用法 大概分为三种:
await + async
await + Promise
await + co + generaor
后记
相关知识参考资料
最后更新于
这有帮助吗?