2016-11-10 312 views
0

我可能是這個得太多,而是包涵......如果我有下面的代碼如何修改bluebird promise中的express.res,並在另一個promise中使用res?

app.get('/api/endpoint', function(req, res, next) { 
    new Promise(function() { 
     // doing something that takes lots of code 
     return someJson 
    }) 
    .then(function(someJson) { 
     // analyze someJson with lots of code 
    }) 
    .then(function() { 
     // do more 
    }) 
    // chain a bunch more promises here 
    .then(function() { 
     res.status(200).send(message) 
    }) 
    .catch(function(err) { 
     // error handling 
    }) 
    .finally(function() { 
     // clean up 
    }) 
}) 

如果承諾鏈變得很長,也可以是導航端點的痛苦。所以,我希望承諾的每一步都是它自己的功能(以簡化上面的代碼)。所以,我可以重寫前2許諾像這樣:

function findSomeJson() { 
    return new Promise(function() { 
     // doing something that takes lots of code 
     return someJson 
    }) 
} 

function analyzeSomeJson(someJson) { 
    return new Promise(function(someJson) { 
     // analyze someJson with lots of code 
    }) 
} 

現在,每一項功能都可以在原來的例子可以使用像這樣:

findSomeJson() 
.then(function(someJson) { 
    return analyzeSomeJson(someJson) 
}) 
// etc... 

但是,如果我需要調整會發生什麼res在那些承諾?我是否需要每次都返回res並在res中存儲一些json?而且,如果我必須使用next(),會發生什麼?我如何確保res在我的承諾鏈最後修改?我不能在finally()這樣做,我必須在我最後的承諾中做到這一點嗎?

+0

什麼是「私人功能」? – Bergi

+0

關閉以解救! – Bergi

+0

私人不需要。刪除它。 – Matt

回答

1

如果你真的想在你的函數中改變res你必須傳遞它。我認爲是傳遞它最簡單的/清潔的方法是使用bind這樣的:

findSomeJson() 
    .then(analyzeSomeJson.bind(this, res)) 
    .then(doMore.bind(this, res)) 
    .then(andEvenMore.bind(this, res))... 

然後analyzeSomeJson的定義是這樣的:

// .bind makes it so that res is the first argument when it is called 
function analyzeSomeJson(res, someJson) { 
    return new Promise(function(someJson) { 
    // analyze someJson with lots of code 
    }) 
} 

但我可能會盡量避免繞過res,以便只有您的控制器必須知道reqres。您可以將所有功能轉移到服務或服務,並讓控制器根據服務返回的內容確定res需要發生什麼。希望這會導致可維護/可測試的代碼。

UPDATE非常簡單的服務例如

// endpoint.js 
var jsonService = require('./jsonService.js'); 

app.get('/api/endpoint', function(req, res, next) { 
    jsonService.getJson() 
    // chain a bunch more promises here 
    .then(function(json) { 
    if(json === null) { 
     return res.status(404).send('Not Found'); 
    } 
    res.status(200).send(json); 
    }) 
    .catch(function(err) { 
     // error handling 
    }); 
}); 

有很多方法,你可以實現你的服務,但它真的只是一個js文件,你在你的「控制器」或endpoint.js要求。無論您輸出什麼,都將是您的「公共」方法。

// jsonService.js 

// "public" methods 
var service = { 
    getJson: function() { 
    return findSomeJson().then(analyzeSomeJson); 
    } 
}; 

module.exports = service; 

// "private" methods 
function findSomeJson() { 
    return new Promise(function() { 
     // doing something that takes lots of code 
     return someJson 
    }); 
} 

function analyzeSomeJson(someJson) { 
    return new Promise(function(someJson) { 
     // analyze someJson with lots of code 
    }); 
} 
+0

+1,建議將'req' /'res'保留在這些函數之外 – Bergi

+0

對不起,您是否有此示例(或鏈接)?我還沒有使用服務模式(如果有的話,我沒有把它叫做)。 – Matt

+0

@Matt我剛剛更新了一個簡單的服務示例的答案。 – Ryan