Javascript 在Node.js中按顺序运行代码
我有一个从数据库获取数据的函数:Javascript 在Node.js中按顺序运行代码,javascript,node.js,asynchronous,promise,Javascript,Node.js,Asynchronous,Promise,我有一个从数据库获取数据的函数: recentItems = function () { Items.find({item_published: true}).exec(function(err,item){ if(!err) return item }); }; 我想这样使用它: var x = recentItems(); recentItems = function (callback) { Items.find({item_published:
recentItems = function () {
Items.find({item_published: true}).exec(function(err,item){
if(!err)
return item
});
};
我想这样使用它:
var x = recentItems();
recentItems = function (callback) {
Items.find({item_published: true}).exec(function(err,item){
if(!err)
callback(item)
});
};
但由于recentItems
的异步行为,此操作失败,且值未定义。我知道我可以将函数更改为使用如下回调:
var x = recentItems();
recentItems = function (callback) {
Items.find({item_published: true}).exec(function(err,item){
if(!err)
callback(item)
});
};
以及:
但是我不想使用这种方法,因为我有这样的情况。我有一个函数,它应该执行两个操作,并将结果发送到数组,然后启动回调并返回值:
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
,主回调被调用,然后从recentItems
获取x
的值,这是由于recentItems
的异步行为造成的。但我需要这两个操作依次运行,一个接一个。在计算完所有这些参数后,最后一行运行并触发回调
我如何解决这个问题?我读到了
承诺
和异步
库,但我不知道哪一个是我的答案。我可以用raw Node.js解决这个问题吗?如果是这样的话,我更愿意这样做。你已经差不多做到了。没有解决回调问题的方法。但是,您当然可以使用回调来做您想要做的事情。只需将其嵌套:
var calc = function(callback){
var arr = [];
getValues(function(b){
arr.push(b);
recentItems(function(result){
var x = result;
arr.push(x);
callback(arr);
});
});
};
你可以试试这样的。它仍然嵌套回调,但代码更干净一些
var callA = function(callback) {
//Run the first call
prompt(callback(data));
}
var callB = function(callback) {
//Some other call
prompt(callback(data));
}
callA(function(dataA) {
callB(function(dataB) {
//Place a handler function here
console.log(dataA + " " + dataB)
})
});
有一些方法可以做你想做的事,但没有一种是完美的 有一个将成为回调天堂的自动取款机,但您可以:
- 嵌套回调(本机的,但非常难看且不可维护的代码)
- (很好,但还是太冗长了)
- (这是一个令人惊叹的库,但与本机相去甚远,而且性能也不酷)
- ES7 transpiler—您现在就可以编写ES7代码,它将为您传输到ES5(例如)
async/await
提出的几乎所有功能,并且它将主要使用本机代码,因此可读性和性能都非常好:
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);
});
}
您可以阅读有关此主题的更多信息。这可能是关于node.js最常见的重复问题之一。您的操作是异步的。无法从同步函数返回结果,因为异步结果将在将来某个时候发生。如果您想链接多个操作,那么要么嵌套回调,要么使用承诺,要么使用异步库。仅供参考,承诺已内置于node.js中,因此它们现在是“raw node.js”,强烈建议使用。@Fcoder:如果您不熟悉异步代码,那么克服它的正确方法就是不要克服它。你已经知道如何处理它,所以就去做吧。一旦你有了更多的经验,看看承诺。请注意,承诺不会消除回调的需要,它们只是重新构造回调以消除嵌套。因此,在学习承诺之前,首先要熟悉常规回调。我不同意重复标记,因为NodeJS 4.0.0是非常新的,现在有新的方法来实现OP想要的。一系列问题,包括异步操作排序示例:,您可能应该提到这是ES6,您可以通过将--harmony标志传递给节点0.11及更高版本来获得它。另外,我建议gor的可读性不要将其全部包装在回调中。类似于:var run=require('co');函数*main(){}run(main)看起来更熟悉。如果出现错误,不要忘记
拒绝承诺!此外,您可能应该使用promise库中的函数。或者只使用exec()
返回(?)的承诺。getValues
在OPs代码中似乎是同步的,不是吗?