2016-03-17 51 views
-1

我想快速地組合中間件以使它們平行,而不是順序,如果你把app.use(path, /* middlewares *,/ callback)放進去。如何將`resolve`注入回調?

我寫了下面的函數:

function makeParallelMiddleware(args) { 
    let makePromises = (req, res) => args.map((func) => { 
    return new Promise((resolve, reject) => { 
     console.log('In promise: ' + func.name); 
     func(req, res, resolve); 
    }) 
    }); 
    return (req, res, next) => Promise.all(makePromises(req, res)).then(next()) 
} 

但是,這似乎並沒有正常工作。我有以下兩種中間件測試:

function middlewareA(req, res, next) { 
    req.A = 1; 
    console.log('I am in A'); 
    setTimeout(() => { 
    console.log('I am in A delay'); 
    if (req.C) { 
     req.C = 'BA' 
    } else { 
     req.C = 'A' 
    } 
    next() 
    }, 1000) 
} 

function middlewareB(req, res, next) { 
    req.B = 1; 
    if (req.C) { 
    req.C = 'AB' 
    } else { 
    req.C = 'B' 
    } 
    next() 
} 

app.get('/parallel', makeParallelMiddleware([middlewareA, middlewareB]) ,(req, res) => { 
    res.send(req.C); 
}); 

當我訪問/parallel,我只能得到「B」,而不是「BA」。

在設置req.C之前,如何解決承諾?我如何糾正這個問題以獲得理想的結果?

+1

'then(next())'should'then(next)'。 –

+0

如果你想遵循承諾路線,你應該讓你的中間件返回承諾。如果由於某種原因你仍然需要回調,那麼你不能僅僅傳遞'resolve',因爲失敗的工作與promise不同。請參閱[這裏](http://stackoverflow.com/q/22519784/1048572)如何正確地從節點式回調獲得承諾。 – Bergi

回答

1

更改此:

return (req, res, next) => Promise.all(makePromises(req, res)).then(next()) 
//             remove parens here ^^ 

這樣:

return (req, res, next) => Promise.all(makePromises(req, res)).then(function(results) { 
    next(); 
}); 

你分別致電next()立即而不是傳遞函數的參考,可以後來被.then()方法調用。此外,next()可能不喜歡將數組傳遞給它,這就是.then()在您的情況下會傳遞的數據,所以更好地包裝在自定義函數中,然後調用普通的next()


而且,你還需要一些錯誤處理,如果你的任何承諾,拒絕他們可以,如果他們拋出異常。

+0

我很確定'next'不喜歡用數組作爲第一個參數來調用。嘗試'.then(next.bind(null,null),next)'而不是。 – Bergi

+0

@Bergi - 是的,我想知道在這種情況下會發生什麼。我編輯過。 – jfriend00

相關問題