You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
function run(fn) {
var g = fn();
function next(data) {
var result = g.next(data)
if (g.done) return resule.value
result.value.then((data) => next(data))
}
next()
}
简单版:
function fetchData(url) {
return function(cb){
setTimeout(function(){
cb({status: 200, data: url})
}, 1000)
}
}
function* gen() {
var r1 = yield fetchData('https://api.github.com/users/github');
var r2 = yield fetchData('https://api.github.com/users/github/followers');
console.log([r1.data, r2.data].join('\n'));
}
function run (gen) {
var gen = gen();
function next(data) {
var result = gen.next(data);
if (result.done) return result.value;
// 如果返回的值是Promise则是通过then来控制继续执行(Promise型)
if (isPromise(result.value)) {
result.value.then((data) => {
next(data)
})
} else {
// 当返回的是函数时(回调函数型)
result.value(next)
}
}
function isPromise(obj) {
return typeof obj.then === 'function'
}
next()
}
完整版:(简版的co库)
function run(gen) {
// co库就是返回一个Promise对象
return new Promise((resolve, reject) => {
// 判断是否是function
if (typeof gen === 'function') gen = gen()
// 如果不是函数或者没值了则转为完成态
if (!gen || typeof gen.next !== 'function') return resolve(gen)
onFulfilled();
// onFulfilled和onRejected其实就是为了收集报错,效果跟var result = gen.throw(res);一样
function onFulfilled(res) {
var ret;
// 如果报错捕捉报错
try {
ret = gen.next(res)
} catch (e) {
return reject(e)
}
next(ret)
}
function onRejected(err) {
var ret;
// 将报错抛出
try {
ret = gen.throw(err)
} catch(e) {
return reject(e)
}
// 继续执行
next(ret)
}
function next(ret) {
// 状态改为完成状态
if (ret.done) return resolve(ret.value);
// 将result.value的值转为Promise
var value = toPromise(ret.value);
// 如果还有值(执行完value值是undefined)是Promise则继续循环调用
if (value && isPromise(value)) return value.then(onFulfilled, onRejected)
// 记录报错
return onRejected(new TypeError(`you may only yield a function, promise but the following object was passed: ${String(ret.value)}`))
}
})
}
// 通用判断是否是promise
function isPromise(obj) {
return typeof obj.then === 'function'
}
// 将返回值转为Promise类型
function toPromise(obj) {
if (isPromise(obj)) return obj;
if ('function' == typeof obj) return thunkToPromise(obj)
return obj;
}
// 将普通函数转为Promise
function thunkToPromise(fn) {
return new Promise((resolve, reject) => {
fn((err, res) => {
if (err) return reject(err);
resolve(res)
})
})
}
async/await
async function iteratorPromise(arr) {
for(let val of arr) {
await val()
}
}
for await of
async function iteratorPromise(arr) {
for await(result of arr) {
console.log(result)
}
}
异步编程
异步编程的目标语法就是,让他更像同步编程。所以它也是从异步回调 => Promise => Generator => Async/await。
下面是如何将尽可能像同步的进化史~
异步回调
Promise的串行调用
promise的串行调用的根本都是实现如下的方式
假设有这些promise需要串行调用
递归实现:
普通循环实现:
reduce实现:
Generator+co库(自动执行函数)
根据Generator每次执行后会把执行权交出,当调用next后又将执行权收回。当配合上自动执行函数则可以将异步代码同步执行。
有两种方式可以做到执行权的交回执行权:
自动执行函数其实就是不断地执行next
基于Promise对象的自动执行
简单版:
完整版:(简版的co库)
async/await
for await of
Promise
目的
解决回调地狱
实现:
符合规范版:(很多实现都是为了符合规范)
Generator
Generator的思想比较像Thunk,每次执行后将结果以函数形式返回,然后next其实就是再次执行。Generator配上一个自动执行函数便可以将异步代码像同步一样。
![image](https://user-images.githubusercontent.com/7886671/80964939-4bde4680-8e44-11ea-8756-3c4880de6c8a.png)
babel这个代码简化后得到的实现
实现
Async
async其实是Generator的语法糖。
优点:
实现并发
1、Promise.all
2、
实现
The text was updated successfully, but these errors were encountered: