异步操作一直以来都是 JavaScript 开发者十分热衷的话题,从 callback、promise 到 generator 再到 async,其过程就像一首奏鸣曲,在向我们讲述着 JavaScript 异步操作的漫漫进程。
Callback hell 的峥嵘岁月
Callback Hell
在 ES6 之前,我们更多的是采用 callback 的方式处理异步的过程,http://callbackhell.com/(如无法打开请复制链接至浏览器打开)中将类似于以下代码中诸多的’)}’这种形状称为’回调地狱’:
(注:左右/上下滑动屏幕可查看全部代码)
fs.readdir(source, function (err, files) {
if (err) {
console.log('Error finding files: ' + err)
} else {
files.forEach(function (filename, fileIndex) {
console.log(filename)
gm(source + filename).size(function (err, values) {
if (err) {
console.log('Error identifying file size: ' + err)
} else {
console.log(filename + ' : ' + values)
aspect = (values.width / values.height)
widths.forEach(function (width, widthIndex) {
height = Math.round(width / aspect)
console.log('resizing ' + filename + 'to ' + height + 'x' + height)
this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
if (err) console.log('Error writing file: ' + err)
})
}.bind(this))
}
})
})
}
})
复制代码
显然,没有人会保持足够的耐心去阅读这样的代码-----如果嵌套的层级更深的话.
怎么解决 Callback Hell
我们先看如下的一段 Javascript 代码:
(注:左右/上下滑动屏幕可查看全部代码)
fs.readFile(’./example.txt’, ‘utf-8’, (err, content) => {
let queryWord = content.substring(0, 4);
db.find(select * from example where keyword = ${ queryWord }
, (err, res) => {
get(/exampleget?count=${res.length}
, data => {
console.log(data);
});
});
});
先读取 example.txt 中的关键字段,查询数据库后根据结果请求数据,其中包含的异步操作有:读取文件、查询数据库、请求数据,这种多层的嵌套显然是不利于阅读与维护的,为了解决这种问题,保持代码的结构整齐、浅显易读不失为一种好的方法:
(注:左右/上下滑动屏幕可查看全部代码)
function getData(count) {
get(`/sampleget?count=${count}`, data => {
console.log(data);
});
}
function queryDB(kw) {
db.find(`select * from sample where kw = ${kw}`, (err, res) => {
getData(res.length);
});
}
function readFile(filepath) {
fs.readFile(filepath, 'utf-8', (err, content) => {
let keyword = content.substring(0, 5);
queryDB(keyword);
});
}
readFile('./sample.txt');
复制代码
对比之下,通过对函数进行命名或者是将函数封装成独立模块,代码会更具有阅读性。
本文转载自 Think 体验设计公众号。
原文链接:https://mp.weixin.qq.com/s/QgC2OjVF4pvltte9V_gkIQ
评论