【发布时间】:2014-07-11 21:03:51
【问题描述】:
我最近经常使用 JavaScript,我试图弄清楚解释器如何确定何时“等待”,以及何时异步转到下一行代码。
以这两个代码示例为例。阅读我的 cmets,了解我的困惑。
1:
function doAThing(thing, callback) {
var someBoolean;
if ( !thing ) {
someBoolean = true;
} else {
someBoolean = false;
}
// Calling the callback function only happens *after* the above if statement,
// meaning the interpreter waits instead of just calling it immediately?
callback(someBoolean);
}
2:
function doOtherThing(thing, callback) {
var someBoolean;
// Some fake ORM, querying a fake DB with a where clause of thing
Model.find().where({ someProperty: thing }).exec(function(err, results){
if ( results ) {
someBoolean = true;
} else {
someBoolean = false;
}
});
// Calling the callback function happens *immediately* and does NOT wait for
// someBoolean to get a value inside the ORM query above before it proceeds,
// so the callback function is given an undefined value for someBoolean
callback(someBoolean);
}
- 在示例 1 中,为什么/如何在调用回调函数之前等待 if 语句完全执行?
- 您如何确定 JavaScript 将“等待”的内容与不等待的内容?
- 在不使用 Q、Async 等库的情况下,有哪些策略可以在原生 javascript 中更优雅地处理此控制流?
我可能有一些术语错误,请随时纠正我。我在这里尝试理解它并感谢任何建议。我也有兴趣阅读与 JavaScript 异步相关的任何资源,但不知道去哪里找。
干杯!
编辑:我知道在示例 #2 中,我可以通过将回调调用放在 ORM 查询的末尾来“强制”仅在 someBoolean 具有值时调用回调。但是,这通常很容易变得笨拙。这是示例#3:
function doSomething(thing, callback) {
// Some fake ORM, querying a fake DB with a where clause of thing
Model.find().where({ someProperty: thing }).exec(function(err, results){
ModelTwo.find().where({ somethingElse: thing }).exec(function(err, results){
ModelThree.find().where({ somethingElse: thing }).exec(function(err, results){
ModelFour.find().where({ somethingElse: thing }).exec(function(err, results) {
// Tons and tons of nesting, getting ever-more-confusing
// and pushing my code further to the right....
callback();
});
});
});
});
}
这是一个非常复杂的例子,但在使用 Node.js 之前我遇到过这样的情况。当我必须在数据库上运行多个查询或多次与某些外部服务交互时,它会很快变得非常混乱,最后我需要调用回调......
我想我的问题是:在原生 javascript 中,有没有更好的方法来避免所有这些嵌套的废话,或者我应该只使用像 Q 或 Async 这样的 Promise 库?
我想要一个更像这样的控制流,在原生 JS 中:
function doAThing(thing, callback) {
var bool1, bool2, bool3, bool4;
SomeLib.someAction().exec(function(err, results){
bool1 = false;
});
SomeLib.someOtherAction().exec(function(err, results){
bool2 = true;
});
SomeOtherLib.action().exec(function(err, results){
bool3 = false;
});
SomeOtherLib.delete().exec(function(err, results){
bool4 = true;
});
// I'd like this only to be called when the above 4 actions are complete,
// **without** nesting all of the actions together and calling the
// callback at the end of the last one. As far as I understand it now...
// I will need a library like async or q in order to have a
// control flow like this?
callback(bool1, bool2, bool3, bool4);
}
【问题讨论】:
-
“示例1,为什么/如何在调用回调函数之前等待if语句完全执行?”它不等待,它执行为了。示例二也不等待,它按顺序执行。不同之处在于示例 2 中 .exec() 的回调由 .exec 在某些操作发生后执行,例如 setTimeout。
-
将函数作为参数传递并不意味着它被调用。这是 Javascript 中非常特别的东西,你必须习惯。阅读:jszen.blogspot.ca/2008/07/…
标签: javascript node.js asynchronous promise q