理想情況下,你應該聽一些事件,而不是投票,但在認識到這是一個臨時的解決辦法...
new Promise()
同步運行它的構造和它會出現controller.storage.users.get()
也同步運行其回調。通過強制遞歸getUser()
調用異步可以避免「最大調用堆棧大小超出」的可能性,最簡單的方法是鏈接new Promise().then(/* recurse from here */)
。
function getUser(userId) {
return new Promise((resolve, reject) => {
controller.storage.users.get(userId, function(err, user) {
if (err) reject(err);
if (!user) reject(new Error('no user for id: ' + useId)); // this branch needs to be catered for
resolve(user); // make `user` available to the .then() below
});
}).then(function(user) {
return (user.orderData && user.orderData.pendingItem) || getUser(userId); // compact and safe
});
}
這應該做的工作,但沒有「最大調用堆棧大小」的保障,代表油炸一個或兩個處理器毫無理由的一個很好的機會。
如建議在評論上面,你可以,而且也應該增加一些延遲到遞歸:
function delay(t) {
return new Promise(function(resolve) {
setTimeout(resolve, t);
});
}
function getUser(userId) {
return new Promise((resolve, reject) => {
controller.storage.users.get(userId, function(err, user) {
if (err) reject(err);
if (!user) reject(new Error('no user for id: ' + useId)); // this branch needs to be catered for
resolve(user); // make `user` available to the .then() below
});
}).then(function(user) {
return (user.orderData && user.orderData.pendingItem) || delay(200).then(function() { // adjust the delay to maximum acceptable value
return getUser(userId);
});
});
}
這看起來像一個電話被用作錘。當然,更好的解決方案是等待設置'user.orderData.pendingItem'的任何內容完成。至少,爲此增加一些延遲。 –
即使你得到這個工作,你基本上做了'while(true)',但遞歸。無論在何處填充「pendingItem」,都會更好,然後在代碼中可以解決它。這樣你就不會在等待完成時創建一個調用堆棧。 –
@ug_我同意您的評論。然而,我目前的問題是所有的數據都被存儲在內存中,而'user'或'orderData'實際上應該存儲在一個數據庫中,以便我可以在查詢上放置一個承諾。但是,我幾乎堅持到我獲得批准才能繼續使用數據庫。 – user3593810