Steven5538

node.js request 與 Express callback 問題

Word count: 496Reading time: 2 min
2014/05/28 Share

近日想要製作 API,不過該 API 內容源自某個需要登入的網站,使用的語言是 node.js,而在 node.js 底下有個非常方便的 module - request,可以對需求網站做 get、post 等等多種需求。
一個基本的 post 配合 Express 可以如下呼叫:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
app.get '/' , (req , res) ->;
res.send login()

login = () ->;
options =
strictSSL: false ,
jar: true ,
form: formData ,
url: 'https://example.com'

request.post options , (err , res , body) ->;
if not err and res.statusCode is 200
# 1. do something with body ...

# 2. do something when post finish and callback the result
result

這時就會遇到一個問題,當 post 還沒完成時,外面一層的 something 就已經做了,所以前台顯示的時候會得到 null,會這樣的原因是因為 node.js 的異步函數調用,所有函數是併發執行,於是這時可以再搭配 另一個 module - async (不得不說,node.js 的 module 真的很多),此時可以將原本的程式碼改寫:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
app.get '/' , (req , res) ->;
res.send login()

login = () ->;
options =
strictSSL: false ,
jar: true ,
form: formData ,
url: 'https://example.com'
async.parallel [
(callback) ->;
request.post options , (err , res , body) ->;
if not err and res.statusCode is 200
# 1. do something with body ...

# First call

(callback) ->;
# 2. do something when post finish and callback the result
result

# Second call , will wait for the first call finish
]

照邏輯來說,第二個 Call 的時候就會將 result callback 給 main function,致使前台顯示內容,不過事情果然不是笨蛋想的那麼簡單,得到的內容依舊是錯誤的,正確的作法應該是將一個值傳入 function 內,在最後的時候再將其 callback。
最後的程式碼應該如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
app.get '/' , (req , res) ->;
login (err , result) ->;
res.send result

login = (callback) ->;
options =
strictSSL: false ,
jar: true ,
form: formData ,
url: 'https://example.com'

async.parallel [
(callback) ->;
request.post options , (err , res , body) ->;
if not err and res.statusCode is 200
# 1. do something with body ...

# First call

(callback) ->;
# 2. do something when post finish and callback the result
callback null , result

# Second call , will wait for the first call finish
] ,
(err , res) ->;
callback null , res

此時在觀看前台就可以得到正確的資料了。

CATALOG