如何避免Javascript中回调函数的嵌套?
大家好,请教一个问题:
如下
getItems
函数,其中
readContent
相对耗时,传入的第二个参数是success回调
function getItems(site) {
var ret = []; // return value
FileUtils.readContent(site, function(result) {
// some codes here...
ret = arrayUnique(result);
return ret; // ??? FIXME
});
return ret; // ??? FIXME
}
我希望能以如下方式获取
getItems
返回值:(返回值都是null)
var items = getItems("test"); // ERROR: always null!!!!!
目前我能想到的一个解决办法是:
getItems
同样接受一个回调函数句柄,在
readContent
的callback中调用,但是这样会导致代码中回调函数的大量嵌套
想请教的就是,
getItems
能否实现阻塞,等待异步操作
readContent
返回,以确保
return ret
?
P.S.
我尝试过jQuery的
$.Deferred()
及
$.when()
,由于不甚了解,所以都没有效果
function getItems(site) {
var ret = []; // return values
var dfd = $.Deferred();
var _readFn = function(dfd) {
FileUtils.readContent(site, function(result) {
// some codes here...
ret = arrayUnique(result);
dfd.resolve();
});
return dfd;
};
$.when(_readFn(dfd)).done(function() {
return ret;
});
}
谢谢!
jquery javascript-jquery 回调函数 JavaScript
碎月葬影233
11 years ago
Answers
因为异步嵌套在代码维护和阅读上的确存在问题, 最近花时间在寻找其解决方案. 以下是问题相关的解答.
- 第一段代码的返回值应该都是[]而不是null, 应该是楼主描述有问题.
- getItems不能实现阻塞. Javascript是单线程(不算webworkers), 如果阻塞执行某些耗时任务, 将会导致其他代码不能执行, 造成如页面UI无法响应的问题.
- 通过使用$.Deferred()和async这样的库和函数, 可以解决嵌套问题, 但不能完成阻塞的功能.
可以参考一下我对于js异步嵌套回调的总结 Javascript异步回调的思考及其解决方案
野生的黑白熊
answered 11 years ago