Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Node.js中按顺序运行代码_Javascript_Node.js_Asynchronous_Promise - Fatal编程技术网

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(例如)
但是,如果您已经在使用最新版本的NodeJS(在编写本文时是4.0.0),并且如果您没有,那么您真的应该使用它,那么实现您想要的功能的最佳方法就是使用生成器

与名为的小型库相结合,它将帮助您实现ES7
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代码中似乎是同步的,不是吗?