2016-10-26 6 views
1

라우팅을 위해 Express를 사용하고 DB 관리를 위해 Sequelize를 사용하고 있습니다.약속이 예상대로 작동하지 않습니다

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}`); 
    }); 
}; 

이 문제는, 내 길에, 나는 내 시청자가 데이터베이스에 삽입되었다 후 console.log('instakbot should\'ve been added by now...'); 때문에 제 기능 findChattersPerRole 이미 함수 findOrCreateViewer로 삽입에서 실행될 것으로 기대합니다. 나는

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)을 반환,'어디'chattersPerRole' 배열이다 ('map, .map' 콜백으로부터)'return findOrCreateViewer (username, role) .then (() => ({username, role})); –

+0

그래서 확산 대신 나는 말할지도 모른다. (되돌아 감 Promise.resolve (단위))? – Kevin

+0

나는'.spread'가 무엇을하는지 모른다. 그것은 약속을 되 돌리는가? 그렇다면 아마도 함수를 변경할 필요는 없지만 첫 번째 주석에 표시된대로 반환 값을 사용하여 무언가를해야합니다. 현재'findOrCreateViewer (username, role);'와 같이 아무것도하지 않고있다. –

답변

2

return {username: ...} 함수가 호출되고, 전에 데이터가 삽입 된 직후 발생 findOrCreateViewer(username, role); 후. 그것은 또한 모든 데이터가 삽입되기 전에 return Promise.resolve(flattenDeep(chattersPerRole));이 발생한다는 것을 의미 등

당신은 findOrCreateViewer 그 약속이 무엇인가를 계속하기 전에 (데이터가 삽입 된 후까지 기다려야 즉) 해결 될 때까지 기다릴 필요가 있으므로, 약속을 반환했다 그밖에.

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}`); 
    }); 
}; 

지금 findChattersPerRole에 의해 반환 약속 findOrCreateViewer에 의해 반환
모든 약속이 해결 된 후 해결 될 것입니다.

+0

시간을내어 설명해 주셔서 감사합니다. 큰 시간을 가져 주셔서 감사합니다. Promise.resolve와 Promise.all의 차이점을 정확히 설명해 주시겠습니까? 나는 이제 무엇을 이해한다. 그러나 나는 내가 그것을 분명히하지 않는 .resolve로 이미하고 있다고 생각했다. 또한'() => ({username, role})''ES6 구문은 return {...}와 동일합니까? 나는 그것이라고 추정한다. 그러나 나는 오히려 확신 할 것이다. 이미 짝짓기에 대한 설명에 다시 한번 감사드립니다. – Kevin

+0

'Promise.resolve()'는'new Promise (resolve => resolve (42))'에 대한 축약 일뿐입니다. 즉, 값을 약속으로 래핑하고 즉시 해결합니다. –

2

약속은 마술을하지 않습니다. 약속을 되 돌리는 것은 함수를 호출하는 것이 막히는 것을 의미하는 것이 아니라 콜백을 쉽게 연결하여 결과와 함께 무엇인가를 할 수 있다는 것을 의미합니다. 당신은

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

관련 문제