2017-05-26 37 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); 
 
    }) 
 
}