在我们日常的前端开发中,异步回调是不可避免的操作,会严重影响我们的编程体验和代码的维护性、阅读性,而 promise 和 generator 可以在一定程度上解决这个问题。它们没有那么神奇,只是代码上的一些小花招,现在我们具体来看看 generator 是如何解决异步回调的问题。
一般的异步回调写法
我们先来看看,ajax 请求的一般写法。
var mysite = 'zengxiaoluan.com';
function ajax (url, callback) {
setTimeout(function (url, callback) {
callback(url)
}, 1000, url, callback)
}
// bad way
ajax('other.com', function (url) {
if (url === mysite) {
console.log('is my site')
} else {
console.log('is not my site')
ajax('zengxiaoluan.com', function (url) {
console.log(url)
})
}
})
上面的代码大致模拟了一个异步请求,一秒之后函数会返回当前请求的 url,如果这个 url 是我的网站则停止请求,否则将继续请求。也许用“请求”这种字眼并不合适,但是在实际开发中我们经常遇到类似的情况,我们得根据上一次的返回结果做下一次的操作。按照传统的调用方式,我们就会产生回调地狱的问题(有没有想到十八层地域这个词?😏)。
generator
我们来看看 generator 如何解决上面的问题,使用同步的方式写异步的代码。直接上代码。
function sync (generator) {
// generate a iterator
var task = generator();
// start excute
var result = task.next();
function step () {
if (!result.done) {
if (typeof result.value === 'function') {
result.value(function (url) {
result = task.next(url)
step();
})
} else {
result = task.next(result.value)
step();
}
}
}
step();
}
function wrapAjax(url) {
return function (callback) {
ajax(url, callback);
}
}
sync(function *() {
var url = yield wrapAjax('other.com');
console.log(url);
if (url == mysite) {
return console.log('is my site')
}
var url2 = yield wrapAjax('zengxiaoluan.com');
if (url2 == mysite) {
return console.log('is my site')
}
})
上面的代码,我们先封装了一个 sync 函数,参数为一个生成器函数。在生成器里我们分别调用了两次 wrapAjax 这个方法去做异步操作······
哎呀,文风突转,感觉写不下去了,大家自己在最新的谷歌浏览器里运行代码。就此打住,我先去吃饭了。
2020-03-30 更新
学习英语是理解编程的第一步,generator 有发电机的意思,而 yield 有产生的意思,两者结合可以源源不断产生电源,很符合生成器函数的特性。而利用 generator 处理异步也可以这样写:
function* generator() {
let init = 10;
let a = yield setTimeout(() => {
g.next(init);
}, 1000);
console.log(a);
let b = yield new Promise(function(res, rej) {
setTimeout(() => {
g.next(a + 1);
}, 1000);
});
console.log(b);
let c = yield setTimeout(() => {
g.next(b + 1);
}, 1000);
console.log(c);
}
let g = generator();
console.log(g.next());
参考链接
- function *
- Contains code and snippets for Functional Programming in Javascript.
《generator 和异步回调》有一个想法
评论已关闭。