【问题标题】:Solve dependency in non blocking function call in nodes解决节点中非阻塞函数调用的依赖关系
【发布时间】:2014-11-07 12:57:48
【问题描述】:

在nodejs中,很多函数调用都是以非阻塞函数的形式实现的。有时这些函数调用之间可能存在依赖关系。例如,当用户登录时,我想先获取用户的用户类型,然后根据用户类型,我可以得到刚刚分配给该用户类型的任务。在非阻塞函数中,我使用嵌套函数调用:

$http.post(url_login, login_request)
     .success(function(req) {
          $http.post(url_get_tasks, req.type)
               .success(function(req) {
                    //update tasks
               })
     })

很多库只提供非阻塞函数,例如 node_redis 库。有没有什么好的方法可以处理嵌套的非阻塞函数调用来解决依赖问题。

【问题讨论】:

  • 看看“异步”模块:特别是“瀑布”功能。

标签: javascript node.js asynchronous node-redis


【解决方案1】:

有一个专门针对这个问题的页面:http://callbackhell.com/

总之,你有选择

如果我没记错的话, 您正在使用 Angular $http 服务,它应该支持适当的 承诺链,所以你可以减少你的代码到

$http.post(url_login, login_request)
    .then(function(req){
         return $http.pos(url_get_tasks, req.type);
    })
    .then(function(req){
         // update tasks
    })
    .catch(function(err){
         // errors from the first AND second call land here
    })

您可以为异步函数编写一个简单的包装器,将它们转换为 Promise:

 // this assumes standard node.js callbacks with the
 // signature (error, data)
 function toPromise(fn){
     return function() {
         var args = Array.prototype.slice.call(arguments);
         var scope = this;
         return new Promise(function(resolve, reject){
             var cb = function(err, data) {
                 return err ? reject(err) : resolve(data);
             };
             args.push(cb);
             fn.apply(scope, args);
         });
     };
  }

  // turn fs.readdir into a promise
  var readdir = toPromise(require('fs').readdir);
  readdir('.')
     .then(function(files){
         console.log(files);
     })
     .catch(function(err){
         console.log('reading files failed');
     }) 

还有一个关于 Angular $http 承诺的问题可能会帮助您更好地理解它们:here

【讨论】:

    【解决方案2】:

    我不是 100% 确定你在问什么,但如果你想减少代码中的嵌套,你可以像这样将内部函数移出:

    function success1(req) {
        //update tasks
    }
    function success2(req) {
        $http.post(url_get_tasks, req.type).success(success1)
    }
    
    $http.post(url_login, login_request).success(success2)
    

    显然你应该选择比success1更好的名字

    【讨论】:

      猜你喜欢
      • 2018-01-02
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      • 2014-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多