我有一个从数据库中获取数据的函数:
recentItems = function () {
Items.find({item_published: true}).exec(function(err,item){
if(!err)
return item
});
};
我想像这样使用它:
var x = recentItems();
但由于 recentItems
的异步行为,此操作失败并返回未定义的值。我知道我可以更改我的函数以使用这样的回调:
recentItems = function (callback) {
Items.find({item_published: true}).exec(function(err,item){
if(!err)
callback(item)
});
};
和:
recentItems(function(result){
var x = result;
});
但我不想使用这种方法,因为我有这样的情况。我有一个函数应该执行两个操作并将结果 pus 到一个数组,然后在它们之后触发回调并返回值:
var calc = function(callback){
var arr = [];
var b = getValues();
arr.push(b);
recentItems(function(result){
var x = result;
arr.push(x);
});
callback(arr);
};
在这种情况下,b
的值被推送到 arr
并调用主回调,然后 x
的值从 中获取>recentItems
由于 recentItems
的异步行为。但是我需要这两个操作依次运行,一个接一个。在计算完所有这些之后,最后一行运行并触发回调。
我该如何解决这个问题?我了解了 Promises
和 Async
库,但我不知道我的答案是哪一个。我可以用原始的 Node.js 来克服这个问题吗?如果是这样,我更愿意这样。
最佳答案
有一些方法可以做你想做的事,但还没有一种是~完美~的。
有一个ES7 proposal of native async/await
那将是回调天堂,但是 atm,您可以:
- 嵌套回调(原生的,但非常丑陋且难以维护的代码)
- Promises (很好,但还是太冗长了)
- Async/Await library (这是一个了不起的库,但与原生相去甚远,而且性能也不酷)
- ES7 转译器 - 您今天可以编写 ES7 代码,它会为您转译为 ES5(例如 Babel)
但是,如果您已经在使用最新版本的 NodeJS(撰写本文时为 4.0.0)——如果您还没有,那么您真的应该——实现您想要的目标的最佳方法是使用 < em>生成器。
与名为 co 的小型图书馆相结合,它将帮助您实现几乎 ES7 async/await
所建议的内容,并且它将主要使用 native 代码,因此可读性和性能都非常好:
var co = require('co');
var calc = co(function *calc() {
var arr = [];
var b = getValues();
arr.push(b);
var items = yield recentItems();
arr.push(items);
return arr;
});
function recentItems() {
return new Promise(function(resolve) {
Items.find({item_published: true}).exec(function(err, item) {
if(!err)
resolve(item);
});
}
您可以阅读有关此主题的更多信息 in this awesome Thomas Hunter's blog post .
关于javascript - 在 Node.js 中顺序运行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32686868/