2017-05-26 44 views
0

我知道节点是所有关于异步的东西,但我想要做的事情串行模式如下:如何做事同步的节点

进行API请求>转化体的XML JSON.stringify>通字符串模板。

request.get({url:url, oauth:oauth}, function(err, res, body){ 
    parseString(body, function(err, result){ 
     output = JSON.stringify(result); 

     res.render('home', { title: 'Fantasy Home', 
       output: output }); 
    }); 
}); 

现在我想按顺序做,但所有的回调我很困惑。

由于res对象不存在,res.render无法嵌套在回调中。让它在外面不起作用,因为它会在回调执行之前运行,所以你会得到“未定义”的输出。

必须有一种方法可以按顺序进行操作。为什么一切都是回调?为什么这些函数不能只返回一个常规的非回调结果?

我该如何做这项工作?

+0

至于为什么:@tjameson解释得很好[这里](https://stackoverflow.com/a/17608144/3378621) –

+2

'res.render不能嵌套在回调中,因为res对象不会'这是完全错误的。 res对象存在。如果你有错误,那么这不是错误的原因 – slebetman

+1

你的代码已经按顺序运行就好了。访问'res'可能不起作用,因为你使用'request.get'回调的'res'参数来映射它。 – Bergi

回答

1

其他人不能不提,为什么你res.render不起作用。 你可能有这样的事情:

app.get('/', function(req, res, next) { // You need the res here to .render 

    request.get({url:url, oauth:oauth}, function(err, res, body){ // But you are using this res instead, which does not have the render method 
     parseString(body, function(err, result){ 
      output = JSON.stringify(result); 

      res.render('home', { title: 'Fantasy Home', 
        output: output }); 
     }); 
    }); 
}); 

阅读代码中的注释。因此,您的解决方案是,请求处理程序使用res.render,将request.get回调中的res重命名为其他内容。

0

你应该使用中间件,承诺是更好的事情来处理节点中的异步,但我会告诉你回调。强烈建议不要使用同步调用阻止您的线程!由于node.js是单线程的。 next()这里是一个回调函数,所以中间件不会允许执行main路由函数(使用res.render)直到next()被调用。您可以根据需要传递尽可能多的中间件。

app.use('/user/:id', middleware, (req, res) => { 
    //here you'll find your data 
    console.log(req.callData); 
    res.render(view, req.callData); 
} 
middleware(req, res, next) => { 
    dotheCall(dataToPass, (err, cb) => { 
     req.callData = cb; 
     // remember about handling errors of course! 
     return next(); 
    }) 
} 
0

JavaScript是单线程的,如果我们使用同步代码那么就会围绕自身的响应时间(node.js中)和所有的一个大问题。由于事件循环的好处,所有东西都以回调方式实现。

你可以把事件循环的深刻理解:https://youtu.be/8aGhZQkoFbQ(非常好交代)

可以使用Promisification的情况下,你要实现:http://bluebirdjs.com/docs/getting-started.html

request.get({url:url, oauth:oauth}, function(err, res, body) { 
 
    // Note :: This is Promisified Function 
 
    return parseString(body) 
 
     .bind(this) 
 
     .then(function(result) { 
 
      output = JSON.stringify(result); 
 

 
      res.render('home', {title: 'Fantasy Home', output: output }); 
 

 
      return true; 
 
     }) 
 
     .catch(function(error) 
 
     { 
 
      // Error Handling Code Here 
 
      // Then send response to client 
 
     }); 
 
});

您可以使用以下方法实施promisified功能

function parseString(body) { 
 
    var Promise = require("bluebird"); 
 

 
    return new Promise(function(resolve,reject) { 
 
     // Your Parsing Logic here 
 

 
     if(is_parsed_successfully) { 
 
      return resolve(parsed_data); 
 
     } 
 

 
     return reject(proper_err_data); 
 
    }) 
 
}