2017-08-11 17 views
0

想象一下,你正在使用國家隊和運動員的數據庫(比如奧運會)。測試您的應用程序時,您每次都創建一個新的數據庫。這裏有兩種型號:使用Sequelize創建多部分數據庫對象:承諾何時完成?

const Team = sequelize.define('team', { 
    name: {type: Sequelize.TEXT, allowNull: false} 
}) 

const Athlete = sequelize.define('athlete', { 
    name: {type: Sequelize.TEXT, allowNull: false} 
}) 

Team.hasMany(Athlete) 
Athlete.belongsTo(Team) 

現在,你必須爲你創造了球隊的函數:

function mock_database() { 
    let team0 = Team.create({ 
     name: 'TeamGB' 
    }).then(team => { 
     generate_athletes(team) 
     // Or maybe I need to return the nested promises? 
     // return generate_athletes(team) 
    }) 

    let team1 = Team.create({ 
     name: 'TeamFr' 
    }).then(team => { 
     generate_athletes(team) 
     // Or maybe I need to return the nested promises? 
     // return generate_athletes(team) 
    }) 

    return [team0, team1] 
} 

現在,generate_athletes創建嵌套的數據庫對象(在隊中的運動員):

function generate_athletes(team) { 
    let athlete0 = Athlete.create({ 
     name: 'John Smith' 
    }).then(athlete => { 
     team.setAthletes(athlete) 
     athlete.setTeam(team) 
    }) 

    let athlete1 = Athlete.create({ 
     name: 'Joanna Smith' 
    }).then(athlete => { 
     team.setAthletes(athlete) 
     athlete.setTeam(team) 
    }) 

    return [athlete0, athlete1] 
} 

在這一點上,我想等到數據庫擁有所有的數據。我可以用Promise.all(mock_database()).then(() => {/*my application starts here*/})來做到這一點,它將等待team0team1這兩個承諾。但是,這是否保證我會隱含地等待athlete0athlete1?或者我需要回復這些承諾,將它們全部納入[team0, team1, promises0, promises1]的大數組中,然後等待?

回答

1

您需要返回嵌套的承諾。如果您沒有返回嵌套承諾,那麼您的頂級承諾將在創建團隊後立即解決(因爲創建運動員是異步的,而您並不等待它完成)。

基本上你會想這樣的事情...

function mock_database() { 
    const team0 = Team.create({ // <-- team0::Promise 
    // ... 
    }); 

    const team1 = Team.create({ // <-- team1::Promise 
    // ... 
    }) 
    .then(team => { 
    return generate_athletes(team); // <-- Will only resolve team1 when this resolves 
    }); 

    return Promise.all([team0, team1]); // Wait for both promises to resolve 
} 

function generate_athletes(team) { 
    const athlete1 = Athlete.create({ // athlete1::Promise 
    // ... 
    }); 

    const athlete2 = Athlete.create({ // athlete2::Promise 
    // ... 
    }); 

    return Promise.all([athlete1, athlete2]); // Wait for both promises to resolve 
} 

除非你明確地返回你的程序沒有獲得承諾的thencatch性能的承諾。所以一定要記住,如果你想等待承諾,你一定需要訪問它!所以總是回報它!

祝你好運:)

編輯:你可以找到一個Promise.all解釋here。本質上,儘管發生的是每個數據庫操作都返回一個承諾。當且僅當數據庫操作成功時,這些承諾纔會解決。由於promise只是普通的JavaScript對象,因此可以將它們保存到變量中。

我最終做的是保存對所有我想解決的承諾的引用,然後使用內置承諾函數等待所有承諾的完成。由於運動員依賴於所創建的球隊,因此我們還需要等待每個球隊創建運動員名單。

我用更多評論標記了代碼!

+0

好吧,在我看來,你認爲'generate_athletes'會返回一個使用'Promise.all()'創建的promise,並將其放入'team0'(另一個放在'team1'中)。但是,如果你返回一系列承諾,例如'return [athlete0,athlete1]',你會期望'team0'(和'team1')是那個數組,不是嗎?因爲我看到的是'team0'和'team1'總是*單個承諾(而不是數組),不管你返回什麼。 – alisianoi

+0

你知道嗎,無視這個問題。我已經使用你的'返回Promise.all()'技巧(它將嵌套的承諾組合成一個傳播的承諾),重新編寫我的數據庫例程,現在它按預期工作。如果你可以添加一個鏈接到某種官方文檔來展示這種方法,那就太棒了。 – alisianoi

+1

只是爲了記錄,如果你返回一個沒有'Promise的數組。所有「,那麼你實際上將立即從'generate_athletes'中解析,因爲數組不是承諾。查看我的答案瞭解更多細節。 –

相關問題