рдПрд▓рд┐рдЧреЗрдВрдЯ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд╕рд╛рде рдпрд╛ рддреЛ рдорда

рдЖрдЗрдП рдереЛрдбрд╝реА рд╕реА рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓рддреЗ рд╣реИрдВред рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рднрд╛рд╖рд╛ рдлрд╝рдВрдХреНрд╢рди рд╣реИред рд╣рдо try...catch рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рдХреЛрдб рд╕рдВрд▓рдЧреНрди try...catch рдирд┐рд░реНрдорд╛рдг рдХреЛ try...catch ред рдпрд╣ рдЖрдкрдХреЛ try рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдирд┐рд╖реНрдкрд╛рджрди рдкрде рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ catch рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд╕рднреА рдЕрдкрд╡рд╛рджреЛрдВ рд╕реЗ рдирд┐рдкрдЯрддрд╛ рд╣реИред рдмреБрд░рд╛ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рд╣рд░ рд╕рдВрднрд╡ рдЧрд▓рддреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреЗ рдмрд┐рдирд╛ рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдп рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЕрдВрддрд╣реАрди ifs рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рд░реЛрдХрдирд╛ рдмреЗрд╣рддрд░ рд╣реИред

рдмрд┐рдирд╛ try...catch рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рдпрд╣ рдПрдХ рдЙрдкрдпреЛрдЧреА рдбрд┐рдЬрд╝рд╛рдЗрди рд╣реИред рд▓реЗрдХрд┐рди рдЙрд╕реЗ рдХреБрдЫ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВред рдФрд░ рдпрд╣ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рдпрд╛ рддреЛ try...catch рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХрд╛рджрд╢реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреЗрдЦреЗрдВрдЧреЗ try...catch ред

рдЬрд╛рд░реА рд░рдЦрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдХреБрдЫ рдмрд┐рдВрджреБрдУрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВред рд▓реЗрдЦ рдорд╛рдирддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдлрд╝рдВрдХреНрд╢рди рд░рдЪрдирд╛ рдФрд░ рдХрд░реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддреЗ рд╣реИрдВред рдФрд░ рдПрдХ рдЪреЗрддрд╛рд╡рдиреАред рдпрджрд┐ рдЖрдк рдкрд╣рд▓реЗ рднрд┐рдХреНрд╖реБрдУрдВ рдХреЗ рдкрд╛рд░ рдирд╣реАрдВ рдЖрдП рд╣реИрдВ, рддреЛ рд╡реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ ... рдЕрдЬреАрдм рд▓рдЧ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕реЗ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЛрдЪ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдкрд╣рд▓реЗ рддреЛ рдпрд╣ рдХрдард┐рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдЕрдЧрд░ рдЖрдк рддреБрд░рдВрдд рднреНрд░рдорд┐рдд рд╣реИрдВ рддреЛ рдЪрд┐рдВрддрд╛ рди рдХрд░реЗрдВред рд╕рдмрдХреЗ рдкрд╛рд╕ рд╣реИред рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ, рдореИрдВрдиреЗ рдХреБрдЫ рд▓рд┐рдВрдХ рд╕реВрдЪреАрдмрджреНрдз рдХрд┐рдП рдЬреЛ рдорджрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд░ рдордд рдорд╛рдиреЛред рджрд┐рдорд╛рдЧ рдореЗрдВ рдШреБрд╕рддреЗ рд╣реА рдпреЗ рдЪреАрдЬреЗрдВ рдирд╢реЗ рдореЗрдВ рдЖ рдЬрд╛рддреА рд╣реИрдВред

рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдЙрджрд╛рд╣рд░рдг


рдЕрдкрд╡рд╛рджреЛрдВ рдХреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдХреНрдпреЛрдВ рдореМрдЬреВрдж рд╣реИрдВ рдФрд░ рдХреНрдпреЛрдВ try...catch рдмреНрд▓реЙрдХ рджрд┐рдЦрд╛рдИ рджрд┐рдПред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдПрдХ рд╕рдорд╕реНрдпрд╛ рдХреЛ рджреЗрдЦреЗрдВ рдЬреЛ рдореИрдВрдиреЗ рдХрдо рд╕реЗ рдХрдо рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдпрдерд╛рд░реНрдерд╡рд╛рджреА рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рд╣рдо рд╕реВрдЪрдирд╛рдУрдВ рдХреА рд╕реВрдЪреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВред рд╣рдордиреЗ рд╕рд░реНрд╡рд░ рд╕реЗ рдбреЗрдЯрд╛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (рдХрд┐рд╕реА рддрд░рд╣) рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рдмрдВрдзрд┐рдд рдХрд┐рдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ, рдмреИрдХреЗрдВрдб рдЗрдВрдЬреАрдирд┐рдпрд░реЛрдВ рдиреЗ рдЗрд╕реЗ CSV рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рднреЗрдЬрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, JSON рдирд╣реАрдВред рдХрдЪреНрдЪрд╛ рдбреЗрдЯрд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

  рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк, рд╕рд╛рдордЧреНрд░реА, рджреЗрдЦреА, href
 2018-10-27T05: 33: 34 + 00: 00, @ рдореИрдбрдордЯрд░ рдиреЗ рдЖрдкрдХреЛ рдЪрд╛рдп, рдЕрдкрдард┐рдд, https: //example.com/invite/tea/3801 рдкрд░ рдЖрдордВрддреНрд░рд┐рдд рдХрд┐рдпрд╛
 2018-10-26T13: 47: 12 + 00: 00, @ queenofhearts рдиреЗ 'рдХреНрд░реЛрдХреЗрдЯ рдЯреВрд░реНрдирд╛рдореЗрдВрдЯ' рдЪрд░реНрдЪрд╛ рдореЗрдВ рдЖрдкрдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛, рджреЗрдЦрд╛, https: //example.com/discussions/croquet/1168
 2018-10-25T03: 50: 08 + 00: 00, @ cheshirecat рдиреЗ рдЖрдкрдХреЛ рдПрдХ рдореБрд╕реНрдХрд░рд╛рд╣рдЯ, рдЕрдкрдард┐рдд, https: //example.com/interactions/grin/88 рднреЗрдЬрд╛ 

рд╣рдо рдЗрд╕реЗ HTML рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

 <ul class="MessageList"> <li class="Message Message--viewed"> <a href="https://example.com/invite/tea/3801" class="Message-link">@madhatter invited you to tea</a> <time datetime="2018-10-27T05:33:34+00:00">27 October 2018</time> <li> <li class="Message Message--viewed"> <a href="https://example.com/discussions/croquet/1168" class="Message-link">@queenofhearts mentioned you in 'Croquet Tournament' discussion</a> <time datetime="2018-10-26T13:47:12+00:00">26 October 2018</time> </li> <li class="Message Message--viewed"> <a href="https://example.com/interactions/grin/88" class="Message-link">@cheshirecat sent you a grin</a> <time datetime="2018-10-25T03:50:08+00:00">25 October 2018</time> </li> </ul> 

рдХрд╛рд░реНрдп рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрднреА CSV рдбреЗрдЯрд╛ рдХреА рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВред рдЪрд▓реЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕рд░рд▓ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдкрд╣рд▓рд╛ рдкрд╛рда рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдлрд╝реАрд▓реНрдб рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддрд╛ рд╣реИ:

 function splitFields(row) { return row.split('","'); } 

рдпрд╣рд╛рдВ рд╕рдорд╛рд░реЛрд╣ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╢реИрдХреНрд╖рд┐рдХ рд╕рд╛рдордЧреНрд░реА рд╣реИред рд╣рдо рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП, рд╕реАрдПрд╕рд╡реА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╕реЗ рдирд╣реАрдВред рдпрджрд┐ рдХрд┐рд╕реА рдПрдХ рд╕рдВрджреЗрд╢ рдореЗрдВ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕рдм рдмрд╣реБрдд рдЧрд▓рдд рд╣реЛрдЧрд╛ред рдХреГрдкрдпрд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ CSV рдбреЗрдЯрд╛ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрднреА рди рдХрд░реЗрдВред рдпрджрд┐ рдЖрдкрдХреЛ рдХрднреА рднреА CSV рдбреЗрдЯрд╛ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдирд╛ рд╣реИ, рддреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХреА рдЧрдИ CSV рдкрд╛рд░реНрд╕рд┐рдВрдЧ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ ред

рдбреЗрдЯрд╛ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдФрд░ рдЗрд╕рд▓рд┐рдП рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдирд╛рдо рд╕реАрдПрд╕рд╡реА рд╣реЗрдбрд░ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдордиреЗ рдХрд┐рд╕реА рддрд░рд╣ рдкрд╣рд▓реЗ рд╣реА рдЯрд╛рдЗрдЯрд▓ рдмрд╛рд░ (рдЙрд╕ рдкрд░ рдмрд╛рдж рдореЗрдВ) рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд┐рдпрд╛ред рд╣рдо рдПрдХ рдРрд╕реЗ рдмрд┐рдВрджреБ рдкрд░ рдЖ рдЧрдП рд╣реИрдВ, рдЬрд╣рд╛рдВ рдХреБрдЫ рдЧрд▓рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╣рдореЗрдВ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рддреНрд░реБрдЯрд┐ рдорд┐рд▓реАред рд╣рдо рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрддреЗ рд╣реИрдВ рдпрджрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рд▓рдВрдмрд╛рдИ рд╢реАрд░реНрд╖рдХ рдкрдЯреНрдЯреА рд╕реЗ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддреА рд╣реИред ( _.zipObject рдПрдХ рд▓реЙрд╢ рд╕рдорд╛рд░реЛрд╣ рд╣реИ )ред

 function zipRow(headerFields, fieldData) { if (headerFields.length !== fieldData.length) { throw new Error("Row has an unexpected number of fields"); } return _.zipObject(headerFields, fieldData); } 

рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдорд╛рд░реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдорд╛рдирд╡-рдкрдврд╝рдиреЗ рдпреЛрдЧреНрдп рджрд┐рдирд╛рдВрдХ рдЬреЛрдбрд╝реЗрдВред рдпрд╣ рдереЛрдбрд╝рд╛ рд╡рд░реНрдмреЛрдЬрд╝ рдирд┐рдХрд▓рд╛, рдХреНрдпреЛрдВрдХрд┐ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдбреЗрдЯ рдлреЙрд░реНрдореЗрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдмрд┐рд▓реНрдХреБрд▓ рд╕рд╣реА рдмрд┐рд▓реНрдЯ-рдЗрди рд╕рдкреЛрд░реНрдЯ рдирд╣реАрдВ рд╣реИред рдФрд░ рдлрд┐рд░, рд╣рдо рд╕рдВрднрд╛рд╡рд┐рдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдХреЛрдИ рдЕрдорд╛рдиреНрдп рджрд┐рдирд╛рдВрдХ рд╕рд╛рдордиреЗ рдЖрдИ рд╣реИ, рддреЛ рд╣рдорд╛рд░рд╛ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрддрд╛ рд╣реИред

 function addDateStr(messageObj) { const errMsg = 'Unable to parse date stamp in message object'; const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; const d = new Date(messageObj.datestamp); if (isNaN(d)) { throw new Error(errMsg); } const datestr = `${d.getDate()} ${months[d.getMonth()]} ${d.getFullYear()}`; return {datestr, ...messageObj}; } 

рдЕрдВрдд рдореЗрдВ, рдСрдмреНрдЬреЗрдХреНрдЯ рд▓реЗрдВ рдФрд░ рдЗрд╕реЗ HTML рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкрд▓реЗрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рд╕ рдХрд░реЗрдВред

 const rowToMessage = _.template(`<li class="Message Message--<%= viewed %>"> <a href="<%= href %>" class="Message-link"><%= content %></a> <time datetime="<%= datestamp %>"><%= datestr %></time> <li>`); 

рдпрд╣ рдорд┐рд▓рд╛ рддреЛ рддреНрд░реБрдЯрд┐ рдкреНрд░рд┐рдВрдЯ рдХрд░рдирд╛ рднреА рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛:

 const showError = _.template(`<li class="Error"><%= message %></li>`); 

рдЬрдм рд╕рдм рдХреБрдЫ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЖрдк рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред

 function processRow(headerFieldNames, row) { try { fields = splitFields(row); rowObj = zipRow(headerFieldNames, fields); rowObjWithDate = addDateStr(rowObj); return rowToMessage(rowObj); } catch(e) { return showError(e); } } 

рддреЛ рд╕рдорд╛рд░реЛрд╣ рддреИрдпрд╛рд░ рд╣реИред рдЖрдЗрдП рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓рддреЗ рд╣реИрдВ, рдЗрд╕ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред

рдЕрдкрд╡рд╛рдж: рдЕрдЪреНрдЫрд╛ рд╣рд┐рд╕реНрд╕рд╛


рддреЛ try...catch рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рдЕрдЪреНрдЫрд╛ рд╣реИ try...catch ? рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, try рдмреНрд▓реЙрдХ рдореЗрдВ рдХрд┐рд╕реА рднреА рдЪрд░рдг рдореЗрдВ рддреНрд░реБрдЯрд┐ рд╣реЛ рд╕рдХрддреА рд╣реИред zipRow() рдФрд░ addDateStr() рд╣рдо рдЬрд╛рдирдмреВрдЭрдХрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдлреЗрдВрдХрддреЗ рд╣реИрдВред рдФрд░ рдЕрдЧрд░ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдЖрддреА рд╣реИ, рддреЛ рдмрд╕ рддреНрд░реБрдЯрд┐ рдХреЛ рдкрдХрдбрд╝реЗрдВ рдФрд░ рдкреГрд╖реНрда рдкрд░ рдХреЛрдИ рднреА рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВред рдЗрд╕ рддрдВрддреНрд░ рдХреЗ рдмрд┐рдирд╛, рдХреЛрдб рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрджрд╕реВрд░рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣рд╛рдБ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИред рдорд╛рди рд▓реЗрдВ рдХрд┐ рдлрд╝рдВрдХреНрд╢рдВрд╕ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдирд╣реАрдВ рдлреЗрдВрдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди null рд▓реМрдЯрддреЗ рд╣реИрдВред

 function processRowWithoutExceptions(headerFieldNames, row) { fields = splitFields(row); rowObj = zipRow(headerFieldNames, fields); if (rowObj === null) { return showError(new Error('Encountered a row with an unexpected number of items')); } rowObjWithDate = addDateStr(rowObj); if (rowObjWithDate === null) { return showError(new Error('Unable to parse date in row object')); } return rowToMessage(rowObj); } 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, if рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЯреЗрдореНрдкреНрд▓реЗрдЯ if ред рдХреЛрдб рдЕрдзрд┐рдХ рдХреНрд░рд┐рдпрд╛ рд╣реИред рдФрд░ рдореВрд▓ рддрд░реНрдХ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рдХрдард┐рди рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, null рд╣рдореЗрдВ рдЬреНрдпрд╛рджрд╛ рдХреБрдЫ рдирд╣реАрдВ рдмрддрд╛рддрд╛ рд╣реИред рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдкрд┐рдЫрд▓рд╛ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╡рд┐рдлрд▓ рдХреНрдпреЛрдВ рд╣реБрдЖред рд╣рдореЗрдВ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдо рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ showError() ред рдЗрд╕ рддрд░рд╣ рдХреЗ рдХреЛрдб рдЧрдВрджрдЧреА рдФрд░ рдЕрдзрд┐рдХ рднреНрд░рд╛рдордХ рд╣реИред

рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдлрд┐рд░ рд╕реЗ рджреЗрдЦреЗрдВред рдпрд╣ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рд╕рдлрд▓ рдкрде рдФрд░ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдХреЛрдб рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрд▓рдЧ рдХрд░рддрд╛ рд╣реИред try рдмреНрд░рд╛рдВрдЪ рдПрдХ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реИ, рдФрд░ catch рдмреНрд░рд╛рдВрдЪ рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реИред рд╕рднреА рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рд╣реЛрддреА рд╣реИрдВред рдФрд░ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдХрд╛рд░реНрдп рд░рд┐рдкреЛрд░реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдЕрд╕рдлрд▓ рдХреНрдпреЛрдВ рд╣реБрдПред рд╕рдм рд╕рдм рдореЗрдВ, рдпрд╣ рдмрд╣реБрдд рдкреНрдпрд╛рд░рд╛ рд▓рдЧрддрд╛ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрд╣реБрдордд рдкрд╣рд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдХрд╛рдлреА рдЙрдкрдпреБрдХреНрдд рдорд╛рдирддрд╛ рд╣реИред рдПрдХ рдЕрд▓рдЧ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреНрдпреЛрдВ?

рдЕрдкрд╡рд╛рдж рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдВ ... рдкрдХрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ


рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЖрдкрдХреЛ рдЗрди рдХрд╖реНрдЯрдкреНрд░рдж рдЧрд▓рддрд┐рдпреЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, try...catch рдЕрдкрдирд╛ рдХрд╛рдо рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдХрд░рддрд╛ рд╣реИред рдЖрдк рд╕рд┐рд░реНрдл рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддреЗ рд╣реИрдВ рдФрд░ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред рд╣рдо рдЙрд╕реЗ рдмрд╛рдж рдореЗрдВ рдкрдХрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рд╣рд░ рдХреЛрдИ рд╣рдореЗрд╢рд╛ рдЗрд╕ рддрд░рд╣ рдХреЗ рдмреНрд▓реЙрдХ рд▓рдЧрд╛рдиреЗ рдХрд╛ рдЗрд░рд╛рджрд╛ рд░рдЦрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рд╣рдореЗрд╢рд╛ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рддреНрд░реБрдЯрд┐ рдХрд╣рд╛рдВ рддрдХ тАЛтАЛрдЬрд╛рддреА рд╣реИред рдФрд░ рдмреНрд▓реЙрдХ рдХреЛ рднреВрд▓рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред рдФрд░ рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЖрдк рдпрд╣ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ, рдЖрдкрдХрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреНрд░реИрд╢ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдкрд╡рд╛рдж рдХреЛрдб рдХреЛ рдкреНрд░рджреВрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдпрд╣рд╛рдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╢реБрджреНрдзрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЪрд░реНрдЪрд╛ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рд▓реЗрдХрд┐рди рдЖрдЗрдП рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╢реБрджреНрдзрддрд╛ рдХреЗ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдкрд╣рд▓реВ рдХреЛ рджреЗрдЦреЗрдВ: рд╕рдВрджрд░реНрднрд╛рддреНрдордХ рдкрд╛рд░рджрд░реНрд╢рд┐рддрд╛ред рд▓рд┐рдВрдХ-рдкрд╛рд░рджрд░реНрд╢реА рдлрд╝рдВрдХреНрд╢рди рд╣рдореЗрд╢рд╛ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдкрд╡рд╛рджреЛрдВ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо рдРрд╕рд╛ рдирд╣реАрдВ рдХрд╣ рд╕рдХрддреЗред рд╡реЗ рдореВрд▓реНрдп рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдХрд┐рд╕реА рднреА рд╕рдордп рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рд╕реЗ рддрд░реНрдХ рдЙрд▓рдЭрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЖрдк рдПрдХ рдЬреАрдд-рдЬреАрдд рд╡рд┐рдХрд▓реНрдк рдвреВрдВрдврддреЗ рд╣реИрдВ - рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХрд╛ рдПрдХ рд╕рд╛рдл рддрд░реАрдХрд╛?

рд╣рдо рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╕рд╛рде рдЖрддреЗ рд╣реИрдВ


рд╢реБрджреНрдз рдХрд╛рд░реНрдп рд╣рдореЗрд╢рд╛ рдПрдХ рдорд╛рди рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ (рднрд▓реЗ рд╣реА рд╡рд╣ рдорд╛рди рдЧрд╛рдпрдм рд╣реЛ)ред рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдХреЛрдб рдХреЛ рдпрд╣ рдорд╛рди рд▓реЗрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╣рдо рд╣рдореЗрд╢рд╛ рдПрдХ рдорд╛рди рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред рддреЛ, рдкрд╣рд▓реЗ рдкреНрд░рдпрд╛рд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рдореБрдЭреЗ рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрджрд┐ рд╡рд┐рдлрд▓рддрд╛ рдкрд░, рд╣рдо рдПрдХ рддреНрд░реБрдЯрд┐ рд╡рд╕реНрддреБ рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ? рдпрд╣реА рд╣реИ, рд╣рдо рдЬрд╣рд╛рдВ рднреА рддреНрд░реБрдЯрд┐ рдХрд░рддреЗ рд╣реИрдВ, рд╣рдо рдРрд╕реА рд╡рд╕реНрддреБ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

 function processRowReturningErrors(headerFieldNames, row) { fields = splitFields(row); rowObj = zipRow(headerFieldNames, fields); if (rowObj instanceof Error) { return showError(rowObj); } rowObjWithDate = addDateStr(rowObj); if (rowObjWithDate instanceof Error) { return showError(rowObjWithDate); } return rowToMessage(rowObj); } 

рдпрд╣ рдЕрдкрд╡рд╛рдж рдХреЗ рдмрд┐рдирд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЙрдиреНрдирдпрди рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рдмреЗрд╣рддрд░ рд╣реИред рд╣рдордиреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХреА рд╣реИред рд▓реЗрдХрд┐рди рд╣рдо рдЕрднреА рднреА рдЗрди рд╕рднреА ifs рд╣реИред рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдПрдирдХреНрд░рд┐рдкреНрдЯ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдпрджрд┐ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдмрдЧ рд╣реИ, рддреЛ рдмрд╛рдХреА рдХреЛрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рди рдХрд░реЗрдВред

рдмрд╣реБрд░реВрдкрддрд╛


рдпрд╣ рдХреИрд╕реЗ рдХрд░рдирд╛ рд╣реИ? рдпрд╣ рдПрдХ рдХрдард┐рди рд╕рдорд╕реНрдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдмрд╣реБрд░реВрдкрддрд╛ рдХреЗ рдЬрд╛рджреВ рдХреА рдорджрдж рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдиреЗ рдкрд╣рд▓реЗ рдмрд╣реБрд░реВрдкрддрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдЪрд┐рдВрддрд╛ рди рдХрд░реЗрдВред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдпрд╣ "рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреА рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдХрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рджрд╛рди рдХрд░ рд░рд╣рд╛ рд╣реИ" (рд╕реНрдЯреНрд░реИрдЬреЗрдирдЕрдк, рдмреАред "рд╕реА + рдЧреНрд▓реЛрдЬрд░реА рдСрдл рдмреНрдпреЛрд░реНрди рд╕реНрдЯреНрд░реИрдЬрд╝реЗрдиреБрдк")ред рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдо рд╕рдорд╛рди рдирд╛рдо рдФрд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЕрд▓рдЧ рд╡реНрдпрд╡рд╣рд╛рд░ред рдПрдХ рдХреНрд▓рд╛рд╕рд┐рдХ рдЙрджрд╛рд╣рд░рдг рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд▓реЙрдЧрд┐рдВрдЧ рд╣реИред рд╣рдо рдЕрдкрдиреА рдкрддреНрд░рд┐рдХрд╛рдУрдВ рдХреЛ рдЙрд╕ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╣рдо рджреЛ рд▓рдХрдбрд╝рд╣рд╛рд░рд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛?

 const consoleLogger = { log: function log(msg) { console.log('This is the console logger, logging:', msg); } }; const ajaxLogger = { log: function log(msg) { return fetch('https://example.com/logger', {method: 'POST', body: msg}); } }; 

рджреЛрдиреЛрдВ рдСрдмреНрдЬреЗрдХреНрдЯ рдПрдХ рд▓реЙрдЧ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдПрдХрд▓ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╡реЗ рдЕрд▓рдЧ рддрд░рд╣ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рд╕реБрдВрджрд░рддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдХреЛрдб рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдХреЙрд▓ .log() , рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рдХрд┐ рдХреМрди рд╕реА рд╡рд╕реНрддреБ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣ consoleLogger рдпрд╛ ajaxLogger consoleLogger рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕рдм рдХреБрдЫ рд╡реИрд╕реЗ рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рдХреЛрдб рдХрд┐рд╕реА рднреА рд╡рд╕реНрддреБ рдХреЗ рд╕рд╛рде рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛:

 function log(logger, message) { logger.log(message); } 

рдПрдХ рдФрд░ рдЙрджрд╛рд╣рд░рдг рд╕рднреА JS рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд▓рд┐рдП .toString() рд╡рд┐рдзрд┐ рд╣реИред рд╣рдо рдХрд┐рд╕реА рднреА рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП .toString() рд╡рд┐рдзрд┐ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╣рдо рдмрдирд╛рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдмрд╛рдж, рдЖрдк рджреЛ рдХрдХреНрд╖рд╛рдПрдВ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ .toString() рд╡рд┐рдзрд┐ рдХреЛ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддреА рд╣реИрдВред рд╣рдо рдЙрдирдХрд╛ рдирд╛рдо Left рдФрд░ Right (рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рдирд╛рдо рдмрддрд╛рдПрдВрдЧреЗ) рдмрддрд╛рдПрдВрдЧреЗред

 class Left { constructor(val) { this._val = val; } toString() { const str = this._val.toString(); return `Left(${str})`; } } 

 class Right { constructor(val) { this._val = val; } toString() { const str = this._val.toString(); return `Right(${str})`; } } 

рдЕрдм рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдПрдВ рдЬреЛ рдЗрди рджреЛ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдкрд░ .toString() рдХрд╣рддрд╛ рд╣реИ:

 function trace(val) { console.log(val.toString()); return val; } trace(new Left('Hello world')); // тжШ Left(Hello world) trace(new Right('Hello world')); // тжШ Right(Hello world); 

рдмрдХрд╛рдпрд╛ рдХреЛрдб рдирд╣реАрдВ, рдореБрдЭреЗ рдкрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реИрдВ рдЬреЛ рдПрдХ рд╣реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдмрд╣реБрд░реВрдкрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рдкрд░ рдзреНрдпрд╛рди рджреЗрдВред рдпрджрд┐ рд╣рдо рдмрдпрд╛рдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдХрд┐рддрдиреЗ? рд╢реВрдиреНрдпред рдПрдХ рднреА рдирд╣реАрдВред рд╣рдордиреЗ рдПрдХ рд╣реА рдХрдерди рдХреЗ рдмрд┐рдирд╛ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдмрдирд╛рдПред рд╢рд╛рдпрдж рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ...

рдмрд╛рдПрдБ рдФрд░ рджрд╛рдПрдБ


рд╣рдорд╛рд░реА рд╕рдорд╕реНрдпрд╛ рдкрд░ рд▓реМрдЯрддреЗ рд╣реБрдПред рд╣рдорд╛рд░реЗ рдХреЛрдб рдХреЗ рд▓рд┐рдП рд╕рдлрд▓ рдФрд░ рдЕрд╕рдлрд▓ рдкрде рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдПрдХ рдЕрдЪреНрдЫреЗ рд░рд╛рд╕реНрддреЗ рдкрд░, рд╣рдо рдмрд╕ рд╢рд╛рдВрддрд┐ рд╕реЗ рдХреЛрдб рдЪрд▓рд╛рдирд╛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ рдЬрдм рддрдХ рдХрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ рдпрд╛ рд╣рдо рдЗрд╕реЗ рд╕рдорд╛рдкреНрдд рдХрд░ рджреЗрддреЗ рд╣реИрдВред рдЕрдЧрд░ рд╣рдо рдЦреБрдж рдХреЛ рдЧрд▓рдд рд░рд╛рд╕реНрддреЗ рдкрд░ рдкрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЕрдм рдХреЛрдб рдЪрд▓рд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рд╣рдо рдЗрди рд░рд╛рд╕реНрддреЛрдВ рдХрд╛ рдирд╛рдо рд╣реИрдкреНрдкреА рдПрдВрдб рд╕реИрдб рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдирд╛рдордХрд░рдг рдкрд░рдВрдкрд░рд╛рдУрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЕрдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рддреЛ, рдЪрд▓реЛ рдмреБрд░реЗ рд░рд╛рд╕реНрддреЗ рдХреЛ рд╡рд╛рдордкрдВрдереА рдХрд╣рддреЗ рд╣реИрдВ, рдФрд░ рд╕рдлрд▓ рдХреЛ - рд╕рд╣реАред

рдЖрдЗрдП рдПрдХ рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдВ рдЬреЛ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЪрд▓рд╛рддрд╛ рд╣реИ рдпрджрд┐ рд╣рдо рдПрдХ рдЕрдЪреНрдЫреЗ рд░рд╛рд╕реНрддреЗ рдкрд░ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдПрдХ рдмреБрд░реЗ рдкрд░ рдЕрдирджреЗрдЦрд╛ рдХрд░реЗрдВ:

 /** * Left represents the sad path. */ class Left { constructor(val) { this._val = val; } runFunctionOnlyOnHappyPath() { // Left is the sad path. Do nothing } toString() { const str = this._val.toString(); return `Left(${str})`; } } 

 /** * Right represents the happy path. */ class Right { constructor(val) { this._val = val; } runFunctionOnlyOnHappyPath(fn) { return fn(this._val); } toString() { const str = this._val.toString(); return `Right(${str})`; } } 

рдХреБрдЫ рдЗрд╕ рддрд░рд╣:

 const leftHello = new Left('Hello world'); const rightHello = new Right('Hello world'); leftHello.runFunctionOnlyOnHappyPath(trace); // does nothing rightHello.runFunctionOnlyOnHappyPath(trace); // тжШ Hello world // я┐й "Hello world" 

рдЕрдиреБрд╡рд╛рдж


рд╣рдо рдХреБрдЫ рдЙрдкрдпреЛрдЧреА рдХреЗ рд▓рд┐рдП рд╕рдВрдкрд░реНрдХ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрднреА рддрдХ рдирд╣реАрдВред рд╣рдорд╛рд░реА .runFunctionOnlyOnHappyPath() рд╡рд┐рдзрд┐ _val рд╕рдВрдкрддреНрддрд┐ _val рд╣реИред рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ, рд▓реЗрдХрд┐рди рдмрд╣реБрдд рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ рдЕрдЧрд░ рд╣рдо рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдЪрд▓рд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдХреНрдпреЛрдВ? рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рд╣рдо рд╕рд╣реА рдпрд╛ рдЧрд▓рдд рд░рд╛рд╕реНрддреЗ рдкрд░ рд╣реИрдВред рдЬреИрд╕реЗ рд╣реА рд╣рдо рд▓реЗрдлреНрдЯ рдФрд░ рд░рд╛рдЗрдЯ рдХреЗ рдмрд╛рд╣рд░ рд╡реИрд▓реНрдпреВ рд▓реЗрддреЗ рд╣реИрдВ, рд╕реВрдЪрдирд╛ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддреА рд╣реИред рддреЛ рд╣рдо рдХреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЕрдВрджрд░ рдирдП _val рд╕рд╛рде рдмрд╛рдПрдВ рдпрд╛ рджрд╛рдПрдВ рд░рд╛рд╕реНрддреЗ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░реЗрдВред рдФрд░ рд╣рдо рдирд╛рдо рдЫреЛрдЯрд╛ рдХрд░ рджреЗрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдпрд╣рд╛рдБ рд╣реИрдВред рд╣рдо рдЬреЛ рдХрд░рддреЗ рд╣реИрдВ, рд╡рд╣ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рд░рд▓ рдорд╛рдиреЛрдВ рдХреА рджреБрдирд┐рдпрд╛ рд╕реЗ рд▓реЗрдлреНрдЯ рдФрд░ рд░рд╛рдЗрдЯ рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо map() рд╡рд┐рдзрд┐ рдХрд╣рддреЗ рд╣реИрдВ:

 /** * Left represents the sad path. */ class Left { constructor(val) { this._val = val; } map() { // Left is the sad path // so we do nothing return this; } toString() { const str = this._val.toString(); return `Left(${str})`; } } 

 /** * Right represents the happy path */ class Right { constructor(val) { this._val = val; } map(fn) { return new Right( fn(this._val) ); } toString() { const str = this._val.toString(); return `Right(${str})`; } } 

рд╣рдо рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдореБрдХреНрдд рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдореЗрдВ рдмрд╛рдПрдБ рдпрд╛ рджрд╛рдПрдБ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

 const leftHello = new Left('Hello world'); const rightHello = new Right('Hello world'); const helloToGreetings = str => str.replace(/Hello/, 'Greetings,'); leftHello.map(helloToGreetings).map(trace); // Doesn't print any thing to the console // я┐й Left(Hello world) rightHello.map(helloToGreetings).map(trace); // тжШ Greetings, world // я┐й Right(Greetings, world) 

рд╣рдордиреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреЛ рдорд╛рд░реНрдЧ рдмрдирд╛рдП рд╣реИрдВред рд╣рдо new Right() , рдпрд╛ рдлреЗрд▓ рд╣реБрдП рдкрде рдкрд░ new Left() рдХреЙрд▓ рдХрд░рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рд╕рдлрд▓ рдкрде рдкрд░ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВред


рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧ рдПрдХ рдкрде рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ: рд╕рдлрд▓ рдпрд╛ рдЕрд╕рдлрд▓ред рдореИрдВрдиреЗ рд╕реНрдХреЙрдЯ рд╡реЗрд▓рд╛рд╕реНрдЪреАрдирд╛ рдХреЗ рдЗрд╕ рд░реЗрд▓рд╡реЗ рд░реВрдкрдХ рдХреЛ рдЪреБрд░рд╛ рд▓рд┐рдпрд╛

рдпрджрд┐ map рдПрдХ рдЕрдЪреНрдЫреЗ рд░рд╛рд╕реНрддреЗ рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЙрд╕рдХреЗ рд╕рд╛рде рдЬрд╛рдПрдВ рдФрд░ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░реЗрдВред рдЕрдЧрд░ рд╣рдо рдЦреБрдж рдХреЛ рдЕрд╕рдлрд▓ рдкрд╛рддреЗ рд╣реИрдВ, рддреЛ рдХреБрдЫ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдмрд╕ рдЖрдЧреЗ рд╡реИрд▓реНрдпреВ рдкрд╛рд╕ рдХрд░рддреЗ рд░рд╣рд┐рдПред рдпрджрд┐ рд╣рдо, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдЕрд╕рдлрд▓ рдкрде рдкрд░ рддреНрд░реБрдЯрд┐ рдбрд╛рд▓рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рдЗрд╕реА рддрд░рд╣ рдХрд╛ tryтАжcatch ред


рдкрде рдХреЗ рд╕рд╛рде рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП .map() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ

рдЬреИрд╕реЗ-рдЬреИрд╕реЗ рдЖрдк рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ, рд▓реЗрдлреНрдЯ рдпрд╛ рд░рд╛рдЗрдЯ рд▓рд┐рдЦрдиреЗ рдореЗрдВ рд╣рд░ рд╕рдордп рдереЛрдбрд╝рд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЖрдЗрдП рдЗрд╕ рд╕рдВрдпреЛрдЬрди рдХреЛ рдпрд╛ рддреЛ рд╕рд░рд▓рддрд╛ рд╕реЗ рдХрд╣реЗрдВ (рдпрд╛ рддреЛ "рдпрд╛ рддреЛ")ред рдпрд╛ рддреЛ рдмрд╛рдПрдВ рдпрд╛ рджрд╛рдПрдВред

рдпрд╛ рддреЛ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реЙрд░реНрдЯрдХрдЯ


рдЗрд╕рд▓рд┐рдП, рдЕрдЧрд▓рд╛ рдХрджрдо рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реИ рддрд╛рдХрд┐ рд╡реЗ рдпрд╛ рддреЛ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдВред рдореВрд▓реНрдп рдХреЗ рд▓рд┐рдП рддреНрд░реБрдЯрд┐ рдпрд╛ рдЕрдзрд┐рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджрд┐рдпрд╛ред рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рдРрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ, рдХреБрдЫ рдордЬрд╛ рдХрд░реЗрдВред рдЖрдЗрдпреЗ рдПрдХ рджреЛ рд╢рд╛рд░реНрдЯрдХрдЯ рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдкрд╣рд▓рд╛ рдПрдХ рд╕реНрдерд┐рд░ рд╡рд┐рдзрд┐ рд╣реИ рдЬрд┐рд╕реЗ .of() рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдирдпрд╛ рд╡рд╛рдордкрдВрдереА рдпрд╛ рдЕрдзрд┐рдХрд╛рд░ рджреЗрддрд╛ рд╣реИред рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

 Left.of = function of(x) { return new Left(x); }; Right.of = function of(x) { return new Right(x); }; 

рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ Left.of() рдФрд░ Right.of() рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдердХрд╛рдК рд╣реИред рдЗрд╕рд▓рд┐рдП рдореИрдВ рдФрд░ рднреА рдЫреЛрдЯреЗ left() рдФрд░ right() рд▓реЗрдмрд▓ рдХреА рдУрд░ рдЭреБрдХ рд░рд╣рд╛ рд╣реВрдБ:

 function left(x) { return Left.of(x); } function right(x) { return Right.of(x); } 

рдЗрди рд╢реЙрд░реНрдЯрдХрдЯреНрд╕ рдХреЗ рд╕рд╛рде, рд╣рдо рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:

 function zipRow(headerFields, fieldData) { const lengthMatch = (headerFields.length == fieldData.length); return (!lengthMatch) ? left(new Error("Row has an unexpected number of fields")) : right(_.zipObject(headerFields, fieldData)); } function addDateStr(messageObj) { const errMsg = 'Unable to parse date stamp in message object'; const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; const d = new Date(messageObj.datestamp); if (isNaN(d)) { return left(new Error(errMsg)); } const datestr = `${d.getDate()} ${months[d.getMonth()]} ${d.getFullYear()}`; return right({datestr, ...messageObj}); } 

рд╕рдВрд╢реЛрдзрд┐рдд рдХрд╛рд░реНрдп рдкреБрд░рд╛рдиреЗ рд▓реЛрдЧреЛрдВ рд╕реЗ рдЗрддрдиреЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИрдВред рд╣рдо рдХреЗрд╡рд▓ рд╡рд╛рдо рдпрд╛ рдЕрдзрд┐рдХрд╛рд░ рдореЗрдВ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдХреЛ рд▓рдкреЗрдЯрддреЗ рд╣реИрдВ, рдЗрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реИред

рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдореБрдЦреНрдп рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рдкрдВрдХреНрддрд┐ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ right() , рдФрд░ рдлрд┐рд░ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд╛рдЬрди рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░реЗрдВ:

 function processRow(headerFields, row) { const fieldsEither = right(row).map(splitFields); // тАж } 

рдпрд╣ рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд░реЗрд╢рд╛рдиреА рддрдм рд╣реЛрддреА рд╣реИ рдЬрдм рдЖрдк zipRow() рд╕рд╛рде рднреА рдРрд╕рд╛ рд╣реА рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ:

  function processRow(headerFields, row) { const fieldsEither = right(row).map(splitFields); const rowObj = fieldsEither.map(zipRow /* wait. this isn't right */); // ... } 

рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ zipRow() рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдо рдЬреЛ ._val .map() рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ ._val рд╕рдВрдкрддреНрддрд┐ рд╕реЗ рдХреЗрд╡рд▓ рдПрдХ рдореВрд▓реНрдп рдорд┐рд▓рддрд╛ рд╣реИред zipRow() рдХреЗ zipRow() рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдерд┐рддрд┐ рдХреЛ рдареАрдХ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

 function zipRow(headerFields) { return function zipRowWithHeaderFields(fieldData) { const lengthMatch = (headerFields.length == fieldData.length); return (!lengthMatch) ? left(new Error("Row has an unexpected number of fields")) : right(_.zipObject(headerFields, fieldData)); }; } 

рдпрд╣ рдЫреЛрдЯрд╛ рд╕рд╛ рдкрд░рд┐рд╡рд░реНрддрди zipRow рдХреЗ рд░реВрдкрд╛рдВрддрд░рдг рдХреЛ рд╕рд░рд▓ zipRow , рдЗрд╕рд▓рд┐рдП рдпрд╣ zipRow .map() рд╕рд╛рде рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛:

 function processRow(headerFields, row) { const fieldsEither = right(row).map(splitFields); const rowObj = fieldsEither.map(zipRow(headerFields)); // ... But now we have another problem ... } 

рд╢рд╛рдорд┐рд▓ рд╣реЛрдВ


.map() рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП splitFields() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ .map() splitFields() рдареАрдХ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ .splitFields() рдпрд╛ рддреЛ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЬрдм рдЖрдкрдХреЛ zipRow() рдЪрд▓рд╛рдирд╛ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдпрд╛ рддреЛ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддреА рд╣реИред рддреЛ .map() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рд╣рдо рдЕрдВрдд рдореЗрдВ рдпрд╛ рддреЛ рдЕрдВрджрд░ рдЪрд▓ рд░рд╣реЗ рд╣реЛрддреЗ рд╣реИрдВред рдпрджрд┐ рд╣рдо рдФрд░ рдЖрдЧреЗ рдмрдврд╝реЗрдВ, рддреЛ рддрдм рддрдХ .map() рд░рд╣реЗрдВ, рдЬрдм рддрдХ рд╣рдо .map() рдЕрдВрджрд░ .map() рдЪрд▓рд╛рддреЗред рд╡рд╣ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рд╣рдореЗрдВ рдЗрди рдиреЗрд╕реНрдЯреЗрдб рдпрд╛ рддреЛ рдЧрдардмрдВрдзрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рддрд░рд╣ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рддреЛ рдЪрд▓рд┐рдП рдПрдХ рдирдИ рд╡рд┐рдзрд┐ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╣рдо .join() :

 /** *Left represents the sad path. */ class Left { constructor(val) { this._val = val; } map() { // Left is the sad path // so we do nothing return this; } join() { // On the sad path, we don't // do anything with join return this; } toString() { const str = this._val.toString(); return `Left(${str})`; } } 

 /** * Right represents the happy path */ class Right { constructor(val) { this._val = val; } map(fn) { return new Right( fn(this._val) ); } join() { if ((this._val instanceof Left) || (this._val instanceof Right)) { return this._val; } return this; } toString() { const str = this._val.toString(); return `Right(${str})`; } } 

рдЕрдм рд╣рдо рдЕрдкрдиреА рд╕рдВрдкрддреНрддрд┐ рдХреЛ тАЬрдЕрдирдкреИрдХтАЭ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 function processRow(headerFields, row) { const fieldsEither = right(row).map(splitFields); const rowObj = fieldsEither.map(zipRow(headerFields)).join(); const rowObjWithDate = rowObj.map(addDateStr).join(); // Slowly getting better... but what do we return? } 

рд╢реНрд░реГрдВрдЦрд▓рд╛


рд╣рдордиреЗ рдПрдХ рд▓рдВрдмрд╛ рд╕рдлрд░ рддрдп рдХрд┐рдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдпрд╛рдж рд░рдЦрдирд╛ рд╣реЛрдЧрд╛ .join() рд╣рд░ рд╕рдордп рдХреЙрд▓ рдХрд░реЗрдВ, рдЬреЛ рдХрд┐ рдХрд╖реНрдЯрдкреНрд░рдж рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдХреЙрд▓ рдкреИрдЯрд░реНрди рд╣реИ .join() рдФрд░ .join() , рддреЛ рдЪрд▓рд┐рдП рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рддреНрд╡рд░рд┐рдд рдПрдХреНрд╕реЗрд╕ рд╡рд┐рдзрд┐ рдмрдирд╛рддреЗ рд╣реИрдВред рдЪрд▓реЛ рдЗрд╕реЗ chain() , рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рд╕рд╛рде рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдмрд╛рдВрдзрддрд╛ рд╣реИ рдЬреЛ рд╡рд╛рдо рдпрд╛ рдЕрдзрд┐рдХрд╛рд░ рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВред

 /** *Left represents the sad path. */ class Left { constructor(val) { this._val = val; } map() { // Left is the sad path // so we do nothing return this; } join() { // On the sad path, we don't // do anything with join return this; } chain() { // Boring sad path, // do nothing. return this; } toString() { const str = this._val.toString(); return `Left(${str})`; } } 

 /** * Right represents the happy path */ class Right { constructor(val) { this._val = val; } map(fn) { return new Right( fn(this._val) ); } join() { if ((this._val instanceof Left) || (this._val instanceof Right)) { return this._val; } return this; } chain(fn) { return fn(this._val); } toString() { const str = this._val.toString(); return `Right(${str})`; } } 

рдпрджрд┐ рд╣рдо рдХрд┐рд╕реА рддреНрд░реБрдЯрд┐ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд░реЗрд▓ рдХреА рд╕рд╛рджреГрд╢реНрдп,ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрд░реЗрдЦ рдкрд░ рджрд┐рдЦрд╛рдирд╛ рдЖрд╕рд╛рди рд╣реИред


рдпрджрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ, рддреЛ .chain () рд╡рд┐рдзрд┐ рдЖрдкрдХреЛ рдмрд╛рдПрдВ рдорд╛рд░реНрдЧ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╕реНрд╡рд┐рдЪ рдХреЗрд╡рд▓ рдПрдХ рд╣реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред

рдХреЛрдб рдХреЛ рдереЛрдбрд╝рд╛ рдХреНрд▓реАрдирд░ рдорд┐рд▓рд╛:

 function processRow(headerFields, row) { const fieldsEither = right(row).map(splitFields); const rowObj = fieldsEither.chain(zipRow(headerFields)); const rowObjWithDate = rowObj.chain(addDateStr); // Slowly getting better... but what do we return? } 

рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХреБрдЫ рдХрд░реЗрдВ


processRow() рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд░реАрдлреИрдХреНрдЯрд░рд┐рдВрдЧ рд▓рдЧрднрдЧ рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЬрдм рд╣рдо рдореВрд▓реНрдп рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ? рдЕрдВрдд рдореЗрдВ, рд╣рдо рдХрд┐рд╕ рддрд░рд╣ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ: рд╡рд╛рдо рдпрд╛ рдЕрдзрд┐рдХрд╛рд░ред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рдЙрдЪрд┐рдд рдЙрдкрд╛рдп рдХрд░реЗрдЧрд╛:

 function either(leftFunc, rightFunc, e) { return (e instanceof Left) ? leftFunc(e._val) : rightFunc(e._val); } 

Left Right. , . :

 function processRow(headerFields, row) { const fieldsEither = right(row).map(splitFields); const rowObj = fieldsEither.chain(zipRow(headerFields)); const rowObjWithDate = rowObj.chain(addDateStr); return either(showError, rowToMessage, rowObjWithDate); } 

, :

 function processRow(headerFields, row) { const rowObjWithDate = right(row) .map(splitFields) .chain(zipRow(headerFields)) .chain(addDateStr); return either(showError, rowToMessage, rowObjWithDate); } 

. try...catch . if- . - , . , processRow() Left Right , right() . .map() .chain() .

ap lift


, . , , CSV, . () :

 function splitCSVToRows(csvData) { // There should always be a header row... so if there's no // newline character, something is wrong. return (csvData.indexOf('\n') < 0) ? left('No header row found in CSV data') : right(csvData.split('\n')); } function processRows(headerFields, dataRows) { // Note this is Array map, not Either map. return dataRows.map(row => processRow(headerFields, row)); } function showMessages(messages) { return `<ul class="Messages">${messages.join('\n')}</ul>`; } 

, , CSV . Either. .map() lodash- . тАж

 function csvToMessages(csvData) { const csvRows = splitCSVToRows(csvData); const headerFields = csvRows.map(_.head).map(splitFields); const dataRows = csvRows.map(_.tail); // What's next? } 

, processRows() . headerFields dataRows Either. - processRows() , Either. processRows .

 function processRows(headerFields) { return function processRowsWithHeaderFields(dataRows) { // Note this is Array map, not Either map. return dataRows.map(row => processRow(headerFields, row)); }; } 

. headerFields , Either, . , headerFields .map() processRows() ?

 function csvToMessages(csvData) { const csvRows = splitCSVToRows(csvData); const headerFields = csvRows.map(_.head).map(splitFields); const dataRows = csvRows.map(_.tail); // How will we pass headerFields and dataRows to // processRows() ? const funcInEither = headerFields.map(processRows); } 

.map() processRows() , . , processRows() . .map() , Either. , Either, funcInEither . . - dataRows . Left Right. .ap() .

, Left:

  // In Left (the sad path) ap() { return this; } 

Right Either :

  // In Right (the happy path) ap(otherEither) { const functionToRun = otherEither._val; return this.map(functionToRun); } 

:

  function csvToMessages(csvData) { const csvRows = splitCSVToRows(csvData); const headerFields = csvRows.map(_.head).map(splitFields); const dataRows = csvRows.map(_.tail); const funcInEither = headerFields.map(processRows); const messagesArr = dataRows.ap(funcInEither); return either(showError, showMessages, messagesArr); } 

.ap() ( Fantasy Land , ). , : ┬л , . , Either┬╗. .ap() , . liftA2() , . , , ┬л┬╗ (lift) ┬л┬╗. ( , .ap() , .of() ). , liftA2 ┬л lift, ┬╗.

, liftA2 :

 function liftA2(func) { return function runApplicativeFunc(a, b) { return b.ap(a.map(func)); }; } 

:

 function csvToMessages(csvData) { const csvRows = splitCSVToRows(csvData); const headerFields = csvRows.map(_.head).map(splitFields); const dataRows = csvRows.map(_.tail); const processRowsA = liftA2(processRows); const messagesArr = processRowsA(headerFields, dataRows); return either(showError, showMessages, messagesArr); } 

CodePen .

рд╕рдЪ? ?


, ? , ? , . , if-. ┬л , , ┬╗. . , . , - . if'. .

. . , - . , . Either , , . . Right, Left. , Left . , either() .

, , . , ( , , ). . , either() csvToMessages() processRow() . - . Either , . Either .

, try...catch . , . . Either , try...catch . . , , . , , . , Crocks , Sanctuary , Folktale Monet . . - .


Source: https://habr.com/ru/post/hi457098/


All Articles