SlideShare a Scribd company logo
1 of 51
Download to read offline
ASYNCHRONOUS
JAVASCRIPT

GET STUFF DONE BY KNOWING WHEN STUFF IS DONE.
WANT TO HEAR A JAVASCRIPT JOKE?

CALLBACK LATER AND
I'LL TELL IT TO YA!
CALLBACKS ARE HOW JAVASCRIPT MANAGES THINGS THAT
NEED TO HAPPEN IN THE FUTURE
fnto dlvrucln( {
ucin eiePnhie)
cnoelg"eas te tk tig ltrly";
osl.o(Bcue hy ae hns ieal.)
}
fnto stpoe){
ucin eUJk(
cnoelg"h dntketmnaslk pn?)
osl.o(Wy o' lpoaic ie us";
stieu(eiePnhie 20)
eTmotdlvrucln, 00;
}
stpoe)
eUJk(;
EVENT PUMP
setUpJoke
deliverPunchline (after 2000 ms)

EXECUTION THREAD
setUpJoke
deliverPunchline
WHAT HAPPENS IF THE EXECUTION THREAD IS BUSY?
fnto dlvrucln( {
ucin eiePnhie)
cnoelg"eas svnhssm bds ttos";
osl.o(Bcue ee a oe aas ato.)
}
fnto cnrvdxml( {
ucin otieEape)
cnoelg"h i sxari o svn";
osl.o(Wy s i fad f ee?)
stieu(eiePnhie 20)
eTmotdlvrucln, 00;
fnPieatrFrETEEYLRENME)
idrmFcoso(XRML_AG_UBR;
}
fnto cnrvdxml(;
ucin otieEape)
EVENT PUMP
contrivedExample
deliverPunchline in 2000 ms (2000 ms are up!)

EXECUTION THREAD
contrivedExample (still finding factors)
deliverPunchline WAY after 2000 ms!
IN JAVASCRIPT, EVENTS
ARE BLOCKED BY
CURRENTLY EXECUTING
CODE.
"In JavaScript, events are blocked by currently
executing code." -RonTime
"
"In JavaScript, events are blocked
by currently executing code." RonTime
" -Your Name Here
EVENT PUMP
user furiously smashing keyboard event
scroll event
mouse click event
deliverPunchline in 100 ms

EXECUTION QUEUE
contrivedExample (still finding factors)
THAT'S COOL, BUT I DON'T USE SETTIMEOUT OR WRITE
FUNCTIONS THAT DO HEAVY COMPUTATION.
A SEQUENCE OF USER EVENTS ARE ASYNCHRONOUS BY
NATURE.
But more importantly...

THE FIRST 'A' IN 'AJAX'
IS 'ASYNCHRONOUS'
(The 'X' in 'Ajax' is 'XML', but we'll ignore that)
fnto laSuf){
ucin odtf(
vrxr=nwXLtpeus(;
a h
e MHtRqet)
xrorayttcag =fnto( {
h.nedsaehne
ucin)
i(h.edSae==4 {
fxrraytt = )
cnoelgxrrsosTx)
osl.o(h.epneet;
}
}
xroe(GT,'di?ea=';
h.pn'E' /otdly5)
xrsn(;
h.ed)
cnoelg"eus sn!)
osl.o(Rqet et";
}
laSuf)
odtf(;
YOU CAN'T WRITE ASYNCHRONOUS CODE SYNCHRONOUSLY
fnto gttf( {
ucin eSuf)
vrxr=nwXLtpeus(;
a h
e MHtRqet)
vrrsls
a eut;
xrorayttcag =fnto( {
h.nedsaehne
ucin)
i(h.edSae==4 {
fxrraytt = )
rsls=xrrsosTx;
eut
h.epneet
}
}
xroe(GT,'di?ea=';
h.pn'E' /otdly5)
xrsn(;
h.ed)
rtr rsls
eun eut;
}
cnoelg"tf i " gttf()
osl.o(Suf s , eSuf);
YOU CAN MAKE SOME ASYNCHRONOUS CODE SYNCHRONOUS,
BUT EXECUTION WILL BLOCK ALL EVENTS
fnto gttf( {
ucin eSuf)
vrxr=nwXLtpeus(;
a h
e MHtRqet)
vrrsls
a eut;
xrorayttcag =fnto( {
h.nedsaehne
ucin)
i(h.edSae==4 {
fxrraytt = )
rsls=xrrsosTx;
eut
h.epneet
}
}
xroe(GT,'di?ea=' fle;/ tidprmi te'sn'prm
h.pn'E' /otdly5, as) / hr aa s h ayc aa
xrsn(;
h.ed)
rtr rsls
eun eut;
}
cnoelg"tf i " gttf()
osl.o(Suf s , eSuf);
HOW DO WE MAKE THE ASYNCHRONOUS CODE MORE
UNDERSTANDABLE?

CALLBACKS
fnto gttf(r,clbc){
ucin eSuful alak
vrxr=nwXLtpeus(;
a h
e MHtRqet)
xrorayttcag =fnto( {
h.nedsaehne
ucin)
i(h.edSae==4 {
fxrraytt = )
clbc(h.epneet;
alakxrrsosTx)
}
}
xroe(GT,ul;
h.pn'E' r)
xrsn(;
h.ed)
}
gttf(/otdly5,fnto(epne {
eSuf'di?ea=' ucinrsos)
cnoelgrsos)
osl.o(epne;
};
)
BUT WHAT IF I NEED TO DO THINGS THAT DEPEND ON EACH
OTHER?
gttf(/srcret,fnto(eut {
eSuf'ue/urn' ucinrsl)
vrueNm =gtaermeutrsl)
a srae
eNmFoRsl(eut;
cnoelg"el,"+ueNm)
osl.o(Hlo
srae;
vrmsaeR =gtesgUIrmeutrsl)
a esgUI
eMsaeRFoRsl(eut;
gttf(esgUI fnto(esgs {
eSufmsaeR, ucinmsae)
vrmsaeon =gtesgCutrmeutmsae)
a esgCut
eMsaeonFoRsl(esgs;
cnoelg
osl.o(
"o hv "+msaeon +"msae.)
Yu ae
esgCut
esgs";
};
)
};
)
WHAT ABOUT (*GASP*) ERRORS?
gttf(/srcret,fnto(eut {
eSuf'ue/urn' ucinrsl)
vrueNm =gtaermeutrsl)
a srae
eNmFoRsl(eut;
cnoelg"el,"+ueNm)
osl.o(Hlo
srae;
vrmsaeR =gtesgUIrmeutrsl)
a esgUI
eMsaeRFoRsl(eut;
gttf(esgUI fnto(esgs {
eSufmsaeR, ucinmsae)
vrmsaeon =gtesgCutrmeutmsae)
a esgCut
eMsaeonFoRsl(esgs;
cnoelg
osl.o(
"o hv "+msaeon +"msae.)
Yu ae
esgCut
esgs";
} fnto(r){
, uciner
cnoelg
osl.o(
"nerrocre gtigmsae:,ermsae;
A ro curd etn esgs" r.esg)
};
)
} fnto(r){
, uciner
cnoelg
osl.o(
"nerrocre gtigue dt:,ermsae;
A ro curd etn sr aa" r.esg)
};
)
gttf(/srcret,fnto(h,er {
eSuf'ue/urn' ucinxr r)
i(r){
fer
cnoelg
osl.o(
"nerrocre gtigue dt:,ermsae;
A ro curd etn sr aa" r.esg)
}
vrueNm =gtaermeutrsls;
a srae
eNmFoRsl(eut)
cnoelg"el,"+ueNm)
osl.o(Hlo
srae;
vrmsaeR =gtesgUIrmeutrsls;
a esgUI
eMsaeRFoRsl(eut)
gttf(esgUI fnto(esgs er {
eSufmsaeR, ucinmsae, r)
i(r){
fer
cnoelg
osl.o(
"nerrocre gtigmsae:,ermsae
A ro curd etn esgs" r.esg)
}
vrmsaeon =gtesgCutrmeutmsae)
a esgCut
eMsaeonFoRsl(esgs;
cnoelg
osl.o(
"o hv "+msaeon +"msae.)
Yu ae
esgCut
esgs";
};
)
};
)
GOOD THINGS WITH THIS APPROACH?
Understandable
Easy to consume
Direct API
PROBLEMS WITH THIS APPROACH?
Readability
Testing
Tight coupling / Wrong direction of dependencies
Pyramid of doom
HOW CAN WE ADDRESS THESE PROBLEMS?
CAN WE MANAGE ASYNCHRONOUS PROCESSES BY SHARING
AN OBJECT BETWEEN THE CONSUMER AND THE PRODUCER?
Consumer -> Shared Object <- Producer
fnto gttfASaeOjc(r){
ucin eSufshrdbetul
vrxr=nwXLtpeus(;
a h
e MHtRqet)
vrsae ={
a hrd
rsls
eut:
nl
ul
}
;
xrorayttcag =fnto( {
h.nedsaehne
ucin)
i(h.edSae==4 {
fxrraytt = )
sae.eut =xrrsosTx;
hrdrsls
h.epneet
}
}
xroe(GT,ul;
h.pn'E' r)
xrsn(;
h.ed)
rtr sae;
eun hrd
}
fnto cetSaeHnlrsae){
ucin raehrdade(hrd
vrhnlr=fnto( {
a ade
ucin)
i(sae.eut){
f!hrdrsls
stieu(ade,
eTmothnlr
}
es {
le
cnoelgsae.eut)
osl.o(hrdrsls;
}
}
rtr hnlr
eun ade;
}

0;
)

vrsae =gttfASaeOjc(di?ea=';
a hrd
eSufshrdbet'otdly5)
cetSaeHnlrsae))
raehrdade(hrd(;
Create an object in a producer that can be told that processing
is done
Get an object from the producer to the consumer so that the
consumer can tell it to do something
fnto gttfWtCodntrul {
ucin eSufihoriao(r)
vrxr=nwXLtpeus(;
a h
e MHtRqet)
vrcodntr=nwCodntr)
a oriao
e oriao(;
xrorayttcag =fnto( {
h.nedsaehne
ucin)
i(h.edSae==4 {
fxrraytt = )
codntraloenTeaasxrrsosTx)
oriao.lDnAdhDtI(h.epneet;
}
}
xroe(GT,ul;
h.pn'E' r)
xrsn(;
h.ed)
rtr codntrcnueOjc(;
eun oriao.osmrbet)
}
gttfWtCodntr'ue/urn'
eSufihoriao(/srcret)
.nTe(ucinrsl){
adhnfnto(eut
vrueNm =gtaermeutrsl)
a srae
eNmFoRsl(eut;
cnoelg"el,"+ueNm)
osl.o(Hlo
srae;
vrmsaeR =gtesgUIrmeutrsl)
a esgUI
eMsaeRFoRsl(eut;
rtr gttfWtCodntrmsaeR)
eun eSufihoriao(esgUI;
}.nTe(ucinrsl){
)adhnfnto(eut
vrmsaeon =gtesgCutrmeutrsl)
a esgCut
eMsaeonFoRsl(eut;
cnoelg"o hv "+msaeon +"msae.)
osl.o(Yu ae
esgCut
esgs";
};
)
fnto Codntr){
ucin oriao(
vrclbcs=[;
a alak
]
vrecpinades=[;
a xetoHnlr
]
rtr {
eun
aloenTeaas
lDnAdhDtI:
fnto(aa {
ucindt)
frvri=0 i<clbcslnt;i+ {
o(a
;
alak.egh +)
clbcsi(aa;
alak[]dt)
}
}
,
tigSrwdp
hnsceeU:
fnto(x {
ucine)
frvri=0 i<clbcslnt;i+ {
o(a
;
alak.egh +)
ecpinadesi(x;
xetoHnlr[]e)
}
}
,
cnueOjc:
osmrbet
fnto( {
ucin)
rtr {
eun
adhn
nTe:
fnto(n er {
ucinf, r)
vrcodntr=Codntr)
a oriao
oriao(;
vrclbc =fnto( {
a alak
ucin)
rsl.nTe(oriao.lDnAdhDtI,codntrtigSrwdp;
eutadhncodntraloenTeaas oriao.hnsceeU)
clbcsps(alak;
alak.uhclbc)
rtr codntrcnueOjc(;
eun oriao.osmrbet)
}
}
}
}
}
PROMISE
PROMISES/A+
A spec that builds out a standard for asynchronous
communication using a shared communication object called a
promise.
SO YOU TURNED NESTED CALLBACKS INTO A CHAIN.

BIG WHOOP!
A promise represents the future value that will be returned.
fnto gttfAPoieul {
ucin eSufsrms(r)
vrxr=nwXLtpeus(;
a h
e MHtRqet)
vrdfre =Qdfr)
a eerd
.ee(;
xrorayttcag =fnto( {
h.nedsaehne
ucin)
i(h.edSae==4 {
fxrraytt = )
i(h.ttsoe==50 {
fxrsauCd = 0)
trw"oehn poe o tesre!;
ho Smtig opd n h evr"
}
es {
le
dfre.eov(SNprexrrsosTx);
eerdrsleJO.as(h.epneet)
}
}
}
xroe(GT,ul;
h.pn'E' r)
xrsn(;
h.ed)
rtr dfre.rms;
eun eerdpoie
}
fnto gtsrnosrms( {
ucin eUeIfAPoie)
rtr gttfAPoie'ue/urn'
eun eSufsrms(/srcret)
.hn
te(
fnto(aa {
ucindt)
cnoelg
osl.o(
"el," dt.ae;
Hlo , aanm)
rtr dt;
eun aa
};
)
}
fnto gtesgssrms(aa {
ucin eMsaeAPoiedt)
rtr gttfAPoiedt.esgUI.hnfnto(aa {
eun eSufsrms(aamsaeR)te(ucindt)
cnoelg
osl.o(
"o hv" dt.esgslnt,"esgs";
Yu ae, aamsae.egh msae.)
rtr dt;
eun aa
};
)
}
Qfalgtsrnosrms)
.cl(eUeIfAPoie
.hngtesgssrms)
te(eMsaeAPoie;
EXCEPTION HANDLING
fnto gtro( {
ucin eErr)
trw"hsi!;
ho O ht"
}
Qfalgtro()
.cl(eErr)
.hngtsrnosrms)
te(eUeIfAPoie
.hngtesgssrms)
te(eMsaeAPoie
.ac(uciner {
cthfnto(r)
cnoelger;
osl.o(r)
};
)
COMPOSITION
fnto mprmsspoie,f){
ucin aPoie(rmss n
rtr Qalpoie)te(ucinrsls {
eun .l(rmss.hnfnto(eut)
vrmpeRsls=[;
a apdeut
]
frvri=0 i<rslslnt;i+ {
o(a
;
eut.egh +)
mpeRslsps(nrslsi);
apdeut.uhf(eut[])
}
rtr mpeRsls
eun apdeut;
};
)
}
fnto srPoie(rmss {
ucin otrmsspoie)
fnto gtaarsl){
ucin eDt(eut
rtr pren(eutdt,1)
eun asItrsl.aa 0;
}
rtr mprmsspoie,gtaa.hnfnto(eut){
eun aPoie(rmss eDt)te(ucinrsls
rtr rslssr(;
eun eut.ot)
};
)
}
fnto stp){
ucin eU(
vrdt =[;
a aa
]
frvri=0 i<1;i+ {
o(a
;
0 +)
dt.uhgttfAPoie
aaps(eSufsrms(
}

'otx'+i)
di?=
);

srPoie(aa.hnfnto(otd {
otrmssdt)te(ucinsre)
frvri=0 i<sre.egh i+ {
o(a
;
otdlnt; +)
cnoelgsre[];
osl.o(otdi)
}
};
)
Promises are more than just a fancy callback system. A promise
stands in place of a future value.
When an object is "thenable", the value can be retrieved in the
future and used directly, making asynchronous concepts look
synchronous.
GOOD THINGS WITH THIS APPROACH
Code is much more flat
Easier to test
We can compose functions that take promises
We can handle exceptions very clearly
We can pass around promises as though they were the actual
value, using .then() to get the result
BAD THINGS WITH THIS APPROACH
Tends to cause some confusion because the abstraction isn't
straightforward
Using this in a public API is considered very opinionated, and
forces consumers of your API to use a specific paradigm
Multiple implementations of this, not all meet the standard
(*cough* jQuery *cough*)
RECAP
Asynchronous processes in JavaScript are handled with
callbacks.
Callback mechanisms introduce some problems such as error
handling, composition, testing.
Callbacks are functions, which are first class objects.
Instead of callbacks, what if we used a different object that
mediates between consumer and producer?
Promise objects are a type of mediator that represent the
future value of an async process.
Promises/A+ is an open standard with a specification.
Promise objects can be used in place of actual values to make
asynchronous code look synchronous.
QUESTIONS?

More Related Content

Similar to Asynchronous java script

Creating windows store java script apps
Creating windows store java script appsCreating windows store java script apps
Creating windows store java script apps
Eugene Zharkov
 
Refactoring to symfony components
Refactoring to symfony componentsRefactoring to symfony components
Refactoring to symfony components
Michael Peacock
 
Introduction to ATS plugins
Introduction to ATS pluginsIntroduction to ATS plugins
Introduction to ATS plugins
PSUdaemon
 
More on Lex
More on LexMore on Lex
More on Lex
Tech_MX
 
Macroprocessor
MacroprocessorMacroprocessor
Macroprocessor
ksanthosh
 

Similar to Asynchronous java script (20)

2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices
2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices
2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices
 
Creating windows store java script apps
Creating windows store java script appsCreating windows store java script apps
Creating windows store java script apps
 
How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...
How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...
How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...
 
Presenting Seq for Node.js
Presenting Seq for Node.jsPresenting Seq for Node.js
Presenting Seq for Node.js
 
JavaScript pitfalls
JavaScript pitfallsJavaScript pitfalls
JavaScript pitfalls
 
JavaFX, because you're worth it
JavaFX, because you're worth itJavaFX, because you're worth it
JavaFX, because you're worth it
 
Arquillian - extensions which you have to take with you to a deserted island
Arquillian - extensions which you have to take with you to a deserted islandArquillian - extensions which you have to take with you to a deserted island
Arquillian - extensions which you have to take with you to a deserted island
 
Flow of events during Media Player creation in Android
Flow of events during Media Player creation in AndroidFlow of events during Media Player creation in Android
Flow of events during Media Player creation in Android
 
nescala 2013
nescala 2013nescala 2013
nescala 2013
 
Refactoring to symfony components
Refactoring to symfony componentsRefactoring to symfony components
Refactoring to symfony components
 
Build a compiler in 2hrs - NCrafts Paris 2015
Build a compiler in 2hrs -  NCrafts Paris 2015Build a compiler in 2hrs -  NCrafts Paris 2015
Build a compiler in 2hrs - NCrafts Paris 2015
 
Introduction to ATS plugins
Introduction to ATS pluginsIntroduction to ATS plugins
Introduction to ATS plugins
 
More on Lex
More on LexMore on Lex
More on Lex
 
Macroprocessor
MacroprocessorMacroprocessor
Macroprocessor
 
Proxy OOP Pattern in PHP
Proxy OOP Pattern in PHPProxy OOP Pattern in PHP
Proxy OOP Pattern in PHP
 
C++ Lambda and concurrency
C++ Lambda and concurrencyC++ Lambda and concurrency
C++ Lambda and concurrency
 
A Backbone.js Tutorial for the Impatient - Part 1
A Backbone.js Tutorial for the Impatient - Part 1A Backbone.js Tutorial for the Impatient - Part 1
A Backbone.js Tutorial for the Impatient - Part 1
 
Area, surface &amp; volume
Area, surface &amp; volumeArea, surface &amp; volume
Area, surface &amp; volume
 
Linq introduction
Linq introductionLinq introduction
Linq introduction
 
Advanced QUnit - Front-End JavaScript Unit Testing
Advanced QUnit - Front-End JavaScript Unit TestingAdvanced QUnit - Front-End JavaScript Unit Testing
Advanced QUnit - Front-End JavaScript Unit Testing
 

Recently uploaded

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Recently uploaded (20)

Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

Asynchronous java script

  • 1. ASYNCHRONOUS JAVASCRIPT GET STUFF DONE BY KNOWING WHEN STUFF IS DONE.
  • 2. WANT TO HEAR A JAVASCRIPT JOKE? CALLBACK LATER AND I'LL TELL IT TO YA!
  • 3. CALLBACKS ARE HOW JAVASCRIPT MANAGES THINGS THAT NEED TO HAPPEN IN THE FUTURE fnto dlvrucln( { ucin eiePnhie) cnoelg"eas te tk tig ltrly"; osl.o(Bcue hy ae hns ieal.) } fnto stpoe){ ucin eUJk( cnoelg"h dntketmnaslk pn?) osl.o(Wy o' lpoaic ie us"; stieu(eiePnhie 20) eTmotdlvrucln, 00; } stpoe) eUJk(;
  • 4. EVENT PUMP setUpJoke deliverPunchline (after 2000 ms) EXECUTION THREAD setUpJoke deliverPunchline
  • 5. WHAT HAPPENS IF THE EXECUTION THREAD IS BUSY? fnto dlvrucln( { ucin eiePnhie) cnoelg"eas svnhssm bds ttos"; osl.o(Bcue ee a oe aas ato.) } fnto cnrvdxml( { ucin otieEape) cnoelg"h i sxari o svn"; osl.o(Wy s i fad f ee?) stieu(eiePnhie 20) eTmotdlvrucln, 00; fnPieatrFrETEEYLRENME) idrmFcoso(XRML_AG_UBR; } fnto cnrvdxml(; ucin otieEape)
  • 6. EVENT PUMP contrivedExample deliverPunchline in 2000 ms (2000 ms are up!) EXECUTION THREAD contrivedExample (still finding factors) deliverPunchline WAY after 2000 ms!
  • 7. IN JAVASCRIPT, EVENTS ARE BLOCKED BY CURRENTLY EXECUTING CODE.
  • 8. "In JavaScript, events are blocked by currently executing code." -RonTime
  • 9. " "In JavaScript, events are blocked by currently executing code." RonTime " -Your Name Here
  • 10. EVENT PUMP user furiously smashing keyboard event scroll event mouse click event deliverPunchline in 100 ms EXECUTION QUEUE contrivedExample (still finding factors)
  • 11. THAT'S COOL, BUT I DON'T USE SETTIMEOUT OR WRITE FUNCTIONS THAT DO HEAVY COMPUTATION.
  • 12. A SEQUENCE OF USER EVENTS ARE ASYNCHRONOUS BY NATURE.
  • 13. But more importantly... THE FIRST 'A' IN 'AJAX' IS 'ASYNCHRONOUS'
  • 14. (The 'X' in 'Ajax' is 'XML', but we'll ignore that)
  • 15. fnto laSuf){ ucin odtf( vrxr=nwXLtpeus(; a h e MHtRqet) xrorayttcag =fnto( { h.nedsaehne ucin) i(h.edSae==4 { fxrraytt = ) cnoelgxrrsosTx) osl.o(h.epneet; } } xroe(GT,'di?ea='; h.pn'E' /otdly5) xrsn(; h.ed) cnoelg"eus sn!) osl.o(Rqet et"; } laSuf) odtf(;
  • 16. YOU CAN'T WRITE ASYNCHRONOUS CODE SYNCHRONOUSLY fnto gttf( { ucin eSuf) vrxr=nwXLtpeus(; a h e MHtRqet) vrrsls a eut; xrorayttcag =fnto( { h.nedsaehne ucin) i(h.edSae==4 { fxrraytt = ) rsls=xrrsosTx; eut h.epneet } } xroe(GT,'di?ea='; h.pn'E' /otdly5) xrsn(; h.ed) rtr rsls eun eut; } cnoelg"tf i " gttf() osl.o(Suf s , eSuf);
  • 17. YOU CAN MAKE SOME ASYNCHRONOUS CODE SYNCHRONOUS, BUT EXECUTION WILL BLOCK ALL EVENTS fnto gttf( { ucin eSuf) vrxr=nwXLtpeus(; a h e MHtRqet) vrrsls a eut; xrorayttcag =fnto( { h.nedsaehne ucin) i(h.edSae==4 { fxrraytt = ) rsls=xrrsosTx; eut h.epneet } } xroe(GT,'di?ea=' fle;/ tidprmi te'sn'prm h.pn'E' /otdly5, as) / hr aa s h ayc aa xrsn(; h.ed) rtr rsls eun eut; } cnoelg"tf i " gttf() osl.o(Suf s , eSuf);
  • 18. HOW DO WE MAKE THE ASYNCHRONOUS CODE MORE UNDERSTANDABLE? CALLBACKS
  • 19. fnto gttf(r,clbc){ ucin eSuful alak vrxr=nwXLtpeus(; a h e MHtRqet) xrorayttcag =fnto( { h.nedsaehne ucin) i(h.edSae==4 { fxrraytt = ) clbc(h.epneet; alakxrrsosTx) } } xroe(GT,ul; h.pn'E' r) xrsn(; h.ed) } gttf(/otdly5,fnto(epne { eSuf'di?ea=' ucinrsos) cnoelgrsos) osl.o(epne; }; )
  • 20. BUT WHAT IF I NEED TO DO THINGS THAT DEPEND ON EACH OTHER?
  • 21. gttf(/srcret,fnto(eut { eSuf'ue/urn' ucinrsl) vrueNm =gtaermeutrsl) a srae eNmFoRsl(eut; cnoelg"el,"+ueNm) osl.o(Hlo srae; vrmsaeR =gtesgUIrmeutrsl) a esgUI eMsaeRFoRsl(eut; gttf(esgUI fnto(esgs { eSufmsaeR, ucinmsae) vrmsaeon =gtesgCutrmeutmsae) a esgCut eMsaeonFoRsl(esgs; cnoelg osl.o( "o hv "+msaeon +"msae.) Yu ae esgCut esgs"; }; ) }; )
  • 23. gttf(/srcret,fnto(eut { eSuf'ue/urn' ucinrsl) vrueNm =gtaermeutrsl) a srae eNmFoRsl(eut; cnoelg"el,"+ueNm) osl.o(Hlo srae; vrmsaeR =gtesgUIrmeutrsl) a esgUI eMsaeRFoRsl(eut; gttf(esgUI fnto(esgs { eSufmsaeR, ucinmsae) vrmsaeon =gtesgCutrmeutmsae) a esgCut eMsaeonFoRsl(esgs; cnoelg osl.o( "o hv "+msaeon +"msae.) Yu ae esgCut esgs"; } fnto(r){ , uciner cnoelg osl.o( "nerrocre gtigmsae:,ermsae; A ro curd etn esgs" r.esg) }; ) } fnto(r){ , uciner cnoelg osl.o( "nerrocre gtigue dt:,ermsae; A ro curd etn sr aa" r.esg) }; )
  • 24. gttf(/srcret,fnto(h,er { eSuf'ue/urn' ucinxr r) i(r){ fer cnoelg osl.o( "nerrocre gtigue dt:,ermsae; A ro curd etn sr aa" r.esg) } vrueNm =gtaermeutrsls; a srae eNmFoRsl(eut) cnoelg"el,"+ueNm) osl.o(Hlo srae; vrmsaeR =gtesgUIrmeutrsls; a esgUI eMsaeRFoRsl(eut) gttf(esgUI fnto(esgs er { eSufmsaeR, ucinmsae, r) i(r){ fer cnoelg osl.o( "nerrocre gtigmsae:,ermsae A ro curd etn esgs" r.esg) } vrmsaeon =gtesgCutrmeutmsae) a esgCut eMsaeonFoRsl(esgs; cnoelg osl.o( "o hv "+msaeon +"msae.) Yu ae esgCut esgs"; }; ) }; )
  • 25. GOOD THINGS WITH THIS APPROACH? Understandable Easy to consume Direct API
  • 26. PROBLEMS WITH THIS APPROACH? Readability Testing Tight coupling / Wrong direction of dependencies Pyramid of doom
  • 27. HOW CAN WE ADDRESS THESE PROBLEMS?
  • 28. CAN WE MANAGE ASYNCHRONOUS PROCESSES BY SHARING AN OBJECT BETWEEN THE CONSUMER AND THE PRODUCER?
  • 29. Consumer -> Shared Object <- Producer
  • 30. fnto gttfASaeOjc(r){ ucin eSufshrdbetul vrxr=nwXLtpeus(; a h e MHtRqet) vrsae ={ a hrd rsls eut: nl ul } ; xrorayttcag =fnto( { h.nedsaehne ucin) i(h.edSae==4 { fxrraytt = ) sae.eut =xrrsosTx; hrdrsls h.epneet } } xroe(GT,ul; h.pn'E' r) xrsn(; h.ed) rtr sae; eun hrd } fnto cetSaeHnlrsae){ ucin raehrdade(hrd vrhnlr=fnto( { a ade ucin) i(sae.eut){ f!hrdrsls stieu(ade, eTmothnlr } es { le cnoelgsae.eut) osl.o(hrdrsls; } } rtr hnlr eun ade; } 0; ) vrsae =gttfASaeOjc(di?ea='; a hrd eSufshrdbet'otdly5) cetSaeHnlrsae)) raehrdade(hrd(;
  • 31. Create an object in a producer that can be told that processing is done Get an object from the producer to the consumer so that the consumer can tell it to do something
  • 32. fnto gttfWtCodntrul { ucin eSufihoriao(r) vrxr=nwXLtpeus(; a h e MHtRqet) vrcodntr=nwCodntr) a oriao e oriao(; xrorayttcag =fnto( { h.nedsaehne ucin) i(h.edSae==4 { fxrraytt = ) codntraloenTeaasxrrsosTx) oriao.lDnAdhDtI(h.epneet; } } xroe(GT,ul; h.pn'E' r) xrsn(; h.ed) rtr codntrcnueOjc(; eun oriao.osmrbet) }
  • 33. gttfWtCodntr'ue/urn' eSufihoriao(/srcret) .nTe(ucinrsl){ adhnfnto(eut vrueNm =gtaermeutrsl) a srae eNmFoRsl(eut; cnoelg"el,"+ueNm) osl.o(Hlo srae; vrmsaeR =gtesgUIrmeutrsl) a esgUI eMsaeRFoRsl(eut; rtr gttfWtCodntrmsaeR) eun eSufihoriao(esgUI; }.nTe(ucinrsl){ )adhnfnto(eut vrmsaeon =gtesgCutrmeutrsl) a esgCut eMsaeonFoRsl(eut; cnoelg"o hv "+msaeon +"msae.) osl.o(Yu ae esgCut esgs"; }; )
  • 34. fnto Codntr){ ucin oriao( vrclbcs=[; a alak ] vrecpinades=[; a xetoHnlr ] rtr { eun aloenTeaas lDnAdhDtI: fnto(aa { ucindt) frvri=0 i<clbcslnt;i+ { o(a ; alak.egh +) clbcsi(aa; alak[]dt) } } , tigSrwdp hnsceeU: fnto(x { ucine) frvri=0 i<clbcslnt;i+ { o(a ; alak.egh +) ecpinadesi(x; xetoHnlr[]e) } } , cnueOjc: osmrbet fnto( { ucin) rtr { eun adhn nTe: fnto(n er { ucinf, r) vrcodntr=Codntr) a oriao oriao(; vrclbc =fnto( { a alak ucin) rsl.nTe(oriao.lDnAdhDtI,codntrtigSrwdp; eutadhncodntraloenTeaas oriao.hnsceeU) clbcsps(alak; alak.uhclbc) rtr codntrcnueOjc(; eun oriao.osmrbet) } } } } }
  • 36. PROMISES/A+ A spec that builds out a standard for asynchronous communication using a shared communication object called a promise.
  • 37. SO YOU TURNED NESTED CALLBACKS INTO A CHAIN. BIG WHOOP!
  • 38. A promise represents the future value that will be returned.
  • 39. fnto gttfAPoieul { ucin eSufsrms(r) vrxr=nwXLtpeus(; a h e MHtRqet) vrdfre =Qdfr) a eerd .ee(; xrorayttcag =fnto( { h.nedsaehne ucin) i(h.edSae==4 { fxrraytt = ) i(h.ttsoe==50 { fxrsauCd = 0) trw"oehn poe o tesre!; ho Smtig opd n h evr" } es { le dfre.eov(SNprexrrsosTx); eerdrsleJO.as(h.epneet) } } } xroe(GT,ul; h.pn'E' r) xrsn(; h.ed) rtr dfre.rms; eun eerdpoie }
  • 40. fnto gtsrnosrms( { ucin eUeIfAPoie) rtr gttfAPoie'ue/urn' eun eSufsrms(/srcret) .hn te( fnto(aa { ucindt) cnoelg osl.o( "el," dt.ae; Hlo , aanm) rtr dt; eun aa }; ) }
  • 41. fnto gtesgssrms(aa { ucin eMsaeAPoiedt) rtr gttfAPoiedt.esgUI.hnfnto(aa { eun eSufsrms(aamsaeR)te(ucindt) cnoelg osl.o( "o hv" dt.esgslnt,"esgs"; Yu ae, aamsae.egh msae.) rtr dt; eun aa }; ) }
  • 43. EXCEPTION HANDLING fnto gtro( { ucin eErr) trw"hsi!; ho O ht" } Qfalgtro() .cl(eErr) .hngtsrnosrms) te(eUeIfAPoie .hngtesgssrms) te(eMsaeAPoie .ac(uciner { cthfnto(r) cnoelger; osl.o(r) }; )
  • 44. COMPOSITION fnto mprmsspoie,f){ ucin aPoie(rmss n rtr Qalpoie)te(ucinrsls { eun .l(rmss.hnfnto(eut) vrmpeRsls=[; a apdeut ] frvri=0 i<rslslnt;i+ { o(a ; eut.egh +) mpeRslsps(nrslsi); apdeut.uhf(eut[]) } rtr mpeRsls eun apdeut; }; ) } fnto srPoie(rmss { ucin otrmsspoie) fnto gtaarsl){ ucin eDt(eut rtr pren(eutdt,1) eun asItrsl.aa 0; } rtr mprmsspoie,gtaa.hnfnto(eut){ eun aPoie(rmss eDt)te(ucinrsls rtr rslssr(; eun eut.ot) }; ) } fnto stp){ ucin eU( vrdt =[; a aa ] frvri=0 i<1;i+ { o(a ; 0 +) dt.uhgttfAPoie aaps(eSufsrms( } 'otx'+i) di?= ); srPoie(aa.hnfnto(otd { otrmssdt)te(ucinsre) frvri=0 i<sre.egh i+ { o(a ; otdlnt; +) cnoelgsre[]; osl.o(otdi) } }; )
  • 45. Promises are more than just a fancy callback system. A promise stands in place of a future value.
  • 46. When an object is "thenable", the value can be retrieved in the future and used directly, making asynchronous concepts look synchronous.
  • 47. GOOD THINGS WITH THIS APPROACH Code is much more flat Easier to test We can compose functions that take promises We can handle exceptions very clearly We can pass around promises as though they were the actual value, using .then() to get the result
  • 48. BAD THINGS WITH THIS APPROACH Tends to cause some confusion because the abstraction isn't straightforward Using this in a public API is considered very opinionated, and forces consumers of your API to use a specific paradigm Multiple implementations of this, not all meet the standard (*cough* jQuery *cough*)
  • 49. RECAP
  • 50. Asynchronous processes in JavaScript are handled with callbacks. Callback mechanisms introduce some problems such as error handling, composition, testing. Callbacks are functions, which are first class objects. Instead of callbacks, what if we used a different object that mediates between consumer and producer? Promise objects are a type of mediator that represent the future value of an async process. Promises/A+ is an open standard with a specification. Promise objects can be used in place of actual values to make asynchronous code look synchronous.