2016-10-26 9 views
1

私はDB管理のためにルーティングとSequelizeにExpressを使用しています。私は期待通りに約束していません

app.get('/api/users/:username', (req, res) => { 
    let username = req.params.username; 
    findChattersPerRole() 
    .then(chattersPerRole => { 
     console.log('instakbot should\'ve been added by now...'); 
    }); 
}); 

関数findChattersPerRoleは、各ユーザーのユーザー名と役割を別のオブジェクトとして持つオブジェクトを戻します。

const findChattersPerRole =() => { 
    return fetch('https://tmi.twitch.tv/group/user/instak/chatters') 
    .then(parseJSON) 
    .then(r => { 
     let chatters = r.chatters; 
     let chattersPerRole = Object.keys(chatters).map(role => { 
     return chatters[role].map(username => { 
      console.log('findOrCreateViewer will be executed after this'); 
      findOrCreateViewer(username, role); 
      return { 
      username: username, 
      role: role 
      }; 
     }); 
     }); 
     return Promise.resolve(flattenDeep(chattersPerRole)); 
    }).catch(err => { 
     console.log(`Error in fetch: ${err}`); 
    }); 
}; 

問題は、私のルートでは、私は私の機能findChattersPerRoleに私はすでに機能findOrCreateViewerでそれらを挿入するので、私の視聴者がデータベースに挿入されてしまった、AFTER console.log('instakbot should\'ve been added by now...');が実行されることを期待しています。私はしかし、私の端末では、あなたが、これはそれが起こっている方法ではないことがわかります

const findOrCreateViewer = (username, role) => { 

    return Viewer.findOrCreate({ 
    where: { 
     username 
    }, 
    defaults: { 
     instakluiten: 5, 
     role 
    } 
    }).spread((unit, created) => { 
    console.log('unit is: ', unit.dataValues.username); 
    if(created){ 
     return `created is ${created}`; 
    }else{ 
     return unit; 
    } 
    }); 

}; 

...これはfindChattersPerRole()が解決されたときので、私のルートで、私はにconsole.logを書く起こることを期待します...私の約束が予定された時間に処刑されないのはなぜですか? Screenshot of my terminal

+1

'findOrCreateViewer'あなたは、その関数が約束を返し、'返しPromise.all(chattersPerRole)のような何かをしたいので、非同期であるように思わを使用する必要があります'.map'コールバックから' return findOrCreateViewer(username、role).then(()=>({username、role})); 'によって作成された約束のうちのどれかです。 –

+0

だから、普及の代わりに、私は言うかもしれません。(返すPromise.resolve(ユニット)); – Kevin

+0

'.spread'が何をするのか分かりません。それは約束を返しますか?はいの場合、おそらくその関数を変更する必要はありませんが、(最初のコメントに示されているように)戻り値で何かする必要があります。現在、あなたはそれを使って何もしていません: 'findOrCreateViewer(username、role);'。 –

答えて

2

findOrCreateViewer(username, role);return {username: ...}は、関数が呼び出されると前に任意のデータが挿入された直後に発生します。つまり、データが挿入される前にreturn Promise.resolve(flattenDeep(chattersPerRole));が発生することを意味します。

あなたはfindOrCreateViewerが約束を返すため、何かを続ける前にその約束が解決するまで待つ必要がありますelse。

chattersPerRoleを約束の配列にして、の後にのみに進むことを約束します。

これはPromise.allで行うのは簡単です:

const findChattersPerRole =() => { 
    return fetch('https://tmi.twitch.tv/group/user/instak/chatters') 
    .then(parseJSON) 
    .then(r => { 
     let chatters = r.chatters; 
     let chattersPerRole = Object.keys(chatters).map(
     role => chatters[role].map(username => { 
      console.log('findOrCreateViewer will be executed after this'); 
      return findOrCreateViewer(username, role).then(
      () => ({username, role}) 
     ); 
     }); 
    ); 
     return Promise.all(flattenDeep(chattersPerRole)); 
    }).catch(err => { 
     console.log(`Error in fetch: ${err}`); 
    }); 
}; 

今​​によって返された約束はfindOrCreateViewerによって返さ結局約束が解決されて解決されます。

+0

私にこれを説明する時間をとってくれてありがとう、それは大きな時間を感謝します。 Promise.resolveとPromise.allの違いが何であるかを説明してください。私は今何をしているのか理解していますが、私は私が明らかにそうではなかった.resolveですでにそれをやっていると思っていました。また、 ''()=>({username、role}) '' ES6の構文はreturn {...}と同じですか?私はそうだと思いますが、私はむしろ確信しています。既に説明してくれてありがとう。 – Kevin

+0

'Promise.resolve()'は実際に 'new Promise(resolve => resolve(42))'の短縮形です。すなわち、値を約束にラップし、即座に解決します。 –

2

約束は魔法をしていません。約束を返すことは、関数を呼び出すことがブロックされることを意味するのではなく、結果を使って何かをするためにコールバックを簡単に連鎖できることを意味します。 `どこ` chattersPerRole`は配列であり、あなたは

function findChattersPerRole() { 
    return fetch('https://tmi.twitch.tv/group/user/instak/chatters') 
    .then(parseJSON) 
    .then(r => { 
     let chatters = r.chatters; 
     let chattersPerRole = Object.keys(chatters).map(role => { 
     return chatters[role].map(username => { 
      console.log('findOrCreateViewer will be executed after this'); 
      return findOrCreateViewer(username, role).then(() => { 
//  ^^^^^^         ^^^^^ 
      return { 
       username: username, 
       role: role 
      }; 
      }); 
     }); 
     }); 
     return Promise.all(flattenDeep(chattersPerRole)); 
//     ^^^ get a promise for an array of results from an array of promises 
    }).catch(err => { 
     console.log(`Error in fetch: ${err}`); 
    }); 
} 
+0

あなたの答えをありがとう、私は本当に私のコードで強調表示し、解説を追加することによって私の間違いを指摘する方法が好きです。 – Kevin

関連する問題