Upgrade to Pro — share decks privately, control downloads, hide ads and more …

おもらし Resolve

135b8d3b5141a5cdfc882f353911103c?s=47 Ryotaro Ko
November 01, 2019

おもらし Resolve

Retty Engineer Meetup#1 (https://retty.connpass.com/event/152101/) で話した LT の公開用スライドです。

135b8d3b5141a5cdfc882f353911103c?s=128

Ryotaro Ko

November 01, 2019
Tweet

Transcript

  1. +4ςετςΫχοΫ
 CZ3ZPUBSP,P!QJLBUFOPS ʙ͓΋Β͠1SPNJTFͷճʙ

  2. ͜Ε͸3FUUZ&OHJOFFS.FFUVQͰ࿩ͨ͠-5ͷެ։༻ࢿྉͰ͢ IUUQTSFUUZDPOOQBTTDPNFWFOU

  3. ͓લ୭ͩ 3FUUZגࣜձࣾ8FCݕࡧνʔϜΤϯδχΞ 3ZPUBSP,P  *%͸େମ!QJLBUFOPS
 େֶଔۀޙೖࣾ ۀ຿ྖҬ όοΫΤϯυ ݕࡧ඼࣭վળ &MBTUJDTFBSDIͷ͓कΓ

    Πϯϑϥख఻͍ 0ODBMM 
  4. ͜Μͳςετ "XFTPNFͳϑΥʔϜ ૹ৴ ॲཧͷྲྀΕ

  5. ͜Μͳςετ ϐΧνϡ΢ ૹ৴ ॲཧͷྲྀΕ

  6. ͜Μͳςετ ϐΧνϡ΢ ૹ৴ ॲཧͷྲྀΕ ೖྗ׬ྃޙɺૹ৴ϘλϯΛԡ͢ ˣ

  7. ͜Μͳςετ ϐΧνϡ΢ ૹ৴ ॲཧͷྲྀΕ ೖྗ׬ྃޙɺૹ৴ϘλϯΛԡ͢ ˣ Ϙλϯ͕άϨʔΞ΢τ͢Δ<BUUSEJTBCMFE> ˣ

  8. ͜Μͳςετ ϐΧνϡ΢ ૹ৴ ॲཧͷྲྀΕ ೖྗ׬ྃޙɺૹ৴ϘλϯΛԡ͢ ˣ Ϙλϯ͕άϨʔΞ΢τ͢Δ<BUUSEJTBCMFE> ˣ "1*௨৴ ˣ

    "1*αʔόʔ
  9. ͜Μͳςετ ϐΧνϡ΢ ૹ৴ ॲཧͷྲྀΕ ೖྗ׬ྃޙɺૹ৴ϘλϯΛԡ͢ ˣ Ϙλϯ͕άϨʔΞ΢τ͢Δ<BUUSEJTBCMFE> ˣ "1*௨৴ ˣ

    ׬ྃͨ͠Βݩʹ໭͢<BUUS> "1*αʔόʔ
  10. ͜Μͳςετ ϐΧνϡ΢ ૹ৴ ॲཧͷྲྀΕ ೖྗ׬ྃޙɺૹ৴ϘλϯΛԡ͢ ˣ Ϙλϯ͕άϨʔΞ΢τ͢Δ<BUUSEJTBCMFE> ˣ "1*௨৴ ˣ

    ׬ྃͨ͠Βݩʹ໭͢<BUUS> "1*αʔόʔ ૹ৴Ϙλϯ͕ԡ͞Ε͔ͯΒ௨৴׬ྃ·Ͱ disabledͰ͋Δ͜ͱΛςετ͍ͨ͠
  11. ίϯϙʔωϯτͷίʔυྫ <template> <form> <input v-model="name" placeholder="Awesome Form"/> <button type="submit" :disabled="loading">ૹ৴</button>

    </form> </template> <script> import { callAPI } from 'API௨৴͢Δ΍ͭ'; export default { data() { return { name: '', loading: false, }; }, methods: { async onSubmit() { this.loading = true; try { await callAPI(this.name); this.$emit('success'); } catch (error) { // ͳΜ͔΍Δ } finally { this.loading = false; } }, }, }; </script>
  12. ίϯϙʔωϯτͷίʔυྫ <template> <form> <input v-model="name" placeholder="Awesome Form"/> <button type="submit" :disabled="loading">ૹ৴</button>

    </form> </template> <script> import { callAPI } from 'API௨৴͢Δ΍ͭ'; export default { data() { return { name: '', loading: false, }; }, methods: { async onSubmit() { this.loading = true; try { await callAPI(this.name); this.$emit('success'); } catch (error) { // ͳΜ͔΍Δ } finally { this.loading = false; } }, }, }; </script> BTZODBXBJU
  13. ΍Γ͍ͨςετ describe('onSubmit', () => { it('activates loading flag when form

    submitted', () => { // before submit expect(wrapper.vm.loading).toBe(false); // waiting API call expect(wrapper.vm.loading).toBe(true); // after submission completed expect(wrapper.vm.loading).toBe(false); }); });
  14. ΍Γ͍ͨςετ describe('onSubmit', () => { it('activates loading flag when form

    submitted', () => { // before submit expect(wrapper.vm.loading).toBe(false); // waiting API call expect(wrapper.vm.loading).toBe(true); // after submission completed expect(wrapper.vm.loading).toBe(false); }); }); ͜͜Ͳ͏͢Μͷ
  15. ωλ͹Β͠ 
 ͓΋Β͠1SPNJTF1SPNJTFͷSFTPMWFϋϯυϥͷείʔϓΛ֎ʹ࿙Β͢ 3FTPMWF

  16. 1SPNJTFSFTPMWF

  17. Promise.resolve(value) • valueͰ3FTPMWF͞ΕͨPromiseΛฦ͢ • ͭ·Γ͜͏ function rizorubu(value) { return new

    Promise(function(resolve){ resolve(value); }) } 1SPNJTFSFTPMWF
  18. function rizorubu(value) { return new Promise(function(resolve){ resolve(value); }) }

  19. let leakedResolve; function rizorubu(value) { return new Promise(function(resolve){ leakedResolve =

    resolve; }) } 3FTPMWFͷ࿙Β͔ͨ͠
  20. let leakedResolve; function rizorubu(value) { return new Promise(function(resolve){ leakedResolve =

    resolve; }) } 3FTPMWFϋϯυϥ͕
 είʔϓ֎ʹ࿙ΕΔ 3FTPMWFͷ࿙Β͔ͨ͠
  21. let leakedResolve; function rizorubu(value) { return new Promise(function(resolve){ leakedResolve =

    resolve; }) } leakedResolve(Promise.resolve("poyo")); BTZODGVODUJPOrezorubu()Λ ޷͖ͳͱ͖ʹ3FTPMWFͰ͖Δʂ 3FTPMWFͷ࿙Β͔ͨ͠ 3FTPMWFϋϯυϥ͕
 είʔϓ֎ʹ࿙ΕΔ
  22. ΍Γ͍ͨςετ describe('onSubmit', () => { it('activates loading flag when form

    submitted', () => { // before submit expect(wrapper.vm.loading).toBe(false); // waiting API call expect(wrapper.vm.loading).toBe(true); // after submission completed expect(wrapper.vm.loading).toBe(false); }); });
  23. ίϯϙʔωϯτͷίʔυྫ <template> <form> <input v-model="name" placeholder="Awesome Form"/> <button type="submit" :disabled="loading">ૹ৴</button>

    </form> </template> <script> import { callAPI } from 'API௨৴͢Δ΍ͭ'; export default { data() { return { name: '', loading: false, }; }, methods: { async onSubmit() { this.loading = true; try { await callAPI(this.name); this.$emit('success'); } catch (error) { // ͳΜ͔΍Δ } finally { this.loading = false; } }, }, }; </script>
  24. ίϯϙʔωϯτͷίʔυྫ <template> <form> <input v-model="name" placeholder="Awesome Form"/> <button type="submit" :disabled="loading">ૹ৴</button>

    </form> </template> <script> import { callAPI } from 'API௨৴͢Δ΍ͭ'; export default { data() { return { name: '', loading: false, }; }, methods: { async onSubmit() { this.loading = true; try { await callAPI(this.name); this.$emit('success'); } catch (error) { // ͳΜ͔΍Δ } finally { this.loading = false; } }, }, }; </script>
  25. ݁ہ͜͏ͳͬͨ let apiResolve; jest.mock('API௨৴͢Δ΍ͭ', () => ({ callAPI: () =>

    new Promise(resolve => { apiResolve = resolve; }), })); describe('AwesomeForm', () => { let wrapper; beforeEach(() => { wrapper = shallowMount(AwesomeForm); }); +FTUͱWVFUFTUVUJMTΛ࢖͍ͬͯ·͢ describe('onSubmit', () => { it('activates loading flag when form submitted', async () => { // before submit expect(wrapper.vm.loading).toBe(false); const submissionPromise = wrapper.vm.onSubmit(); // waiting API call await wrapper.vm.$nextTick(); expect(wrapper.vm.loading).toBe(true); apiResolve(Promise.resolve(true)); await submissionPromise; // after submission completed expect(wrapper.vm.loading).toBe(false); }); }); });
  26. ݁ہ͜͏ͳͬͨ let apiResolve; jest.mock('API௨৴͢Δ΍ͭ', () => ({ callAPI: () =>

    new Promise(resolve => { apiResolve = resolve; }), })); describe('AwesomeForm', () => { let wrapper; beforeEach(() => { wrapper = shallowMount(AwesomeForm); }); +FTUͱWVFUFTUVUJMTΛ࢖͍ͬͯ·͢ describe('onSubmit', () => { it('activates loading flag when form submitted', async () => { // before submit expect(wrapper.vm.loading).toBe(false); const submissionPromise = wrapper.vm.onSubmit(); // waiting API call await wrapper.vm.$nextTick(); expect(wrapper.vm.loading).toBe(true); apiResolve(Promise.resolve(true)); await submissionPromise; // after submission completed expect(wrapper.vm.loading).toBe(false); }); }); }); jest.mock Ͱ Λஔ͖׵͑ import { callAPI } from 'API௨৴͢Δ΍ͭ';
  27. ݁ہ͜͏ͳͬͨ let apiResolve; jest.mock('API௨৴͢Δ΍ͭ', () => ({ callAPI: () =>

    new Promise(resolve => { apiResolve = resolve; }), })); describe('AwesomeForm', () => { let wrapper; beforeEach(() => { wrapper = shallowMount(AwesomeForm); }); describe('onSubmit', () => { it('activates loading flag when form submitted', async () => { // before submit expect(wrapper.vm.loading).toBe(false); const submissionPromise = wrapper.vm.onSubmit(); // waiting API call await wrapper.vm.$nextTick(); expect(wrapper.vm.loading).toBe(true); apiResolve(Promise.resolve(true)); await submissionPromise; // after submission completed expect(wrapper.vm.loading).toBe(false); }); }); }); +FTUͱWVFUFTUVUJMTΛ࢖͍ͬͯ·͢ jest.mock Ͱ Λஔ͖׵͑ import { callAPI } from 'API௨৴͢Δ΍ͭ'; ͓΋Β͠
  28. ݁ہ͜͏ͳͬͨ let apiResolve; jest.mock('API௨৴͢Δ΍ͭ', () => ({ callAPI: () =>

    new Promise(resolve => { apiResolve = resolve; }), })); describe('AwesomeForm', () => { let wrapper; beforeEach(() => { wrapper = shallowMount(AwesomeForm); }); describe('onSubmit', () => { it('activates loading flag when form submitted', async () => { // before submit expect(wrapper.vm.loading).toBe(false); const submissionPromise = wrapper.vm.onSubmit(); // waiting API call await wrapper.vm.$nextTick(); expect(wrapper.vm.loading).toBe(true); apiResolve(Promise.resolve(true)); await submissionPromise; // after submission completed expect(wrapper.vm.loading).toBe(false); }); }); }); +FTUͱWVFUFTUVUJMTΛ࢖͍ͬͯ·͢ MPBEJOHUSVF Λݕূͯ͠3FTPMWF ΦέΦέΦοέʔ
  29. Promise.reject(reason) • reasonʹΑΓ3FKFDU͞ΕͨPromiseΛฦ͢ • ɹɹ
 Έ͍ͨʹॻ͘͜ͱͰΤϥʔ࣌ͷςετ΋Ͱ͖·͢ 1SPNJTFSFKFDU leakedResolve(Promise.reject(new Error("something happened")))

  30. References: Mozilla. "Promise.reject()". MDN Web docs. 2019/3/23. https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject Mozilla. "Promise.resolve()".

    MDN Web docs. 2019/3/18. https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve azu. "Javascript Promise ͷຊ". Ver 1.6.5. https://azu.github.io/promises-book/