You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Asynchronous JavaScript can be confusing, especially for beginners. A simple, consistent, and standard programming model could help to smooth out everyone's learning curve.
Which types of changes would be made?
Breaking change (Add-on libraries or sketches will work differently even if their code stays the same.)
Systemic change (Many features or contributor workflows will be affected.)
Overdue change (Modifications will be made that have been desirable for a long time.)
Unsure (The community can help to determine the type of change.)
Most appropriate sub-area of p5.js?
Accessibility
Color
Core/Environment/Rendering
Data
DOM
Events
Image
IO
Math
Typography
Utilities
WebGL
Build process
Unit testing
Internationalization
Friendly errors
Other (specify if possible)
What's the problem?
p5.js' asynchronous programming model currently uses callbacks. It works, but most of the JavaScript ecosystem has migrated to Promises because they're easier to reason about, especially when used with async/await.
What's the solution?
I suggest that we use Promises and async/await consistently across the API. Most asynchronous functions uses Promises internally, so the implementation would probably be straightforward.
Here's an example of loading an image based on feedback in #6767:
// Load a cat.letimg;asyncfunctionsetup(){img=awaitload("cat.jpg");}functiondraw(){image(img,0,0);}
// Load two cats.letimg1;letimg2;asyncfunctionsetup(){img1=awaitload("cat1.jpg");img2=awaitload("cat2.jpg");}functiondraw(){image(img1,0,0);image(img2,50,0);}
// Use .then() to draw a cat when it arrives.functionsetup(){letdata=load("cat.jpg");data.then(drawCat);createCanvas(400,400);circle(200,200,100);}functiondrawCat(img){image(img,0,0);}
// Use .catch() to handle a loading error.functionsetup(){letdata=load("cat.jpg");data.then(drawCat).catch(logError);createCanvas(400,400);circle(200,200,100);}functiondrawCat(img){image(img,0,0);}functionlogError(error){console.error("🙀",error);}
And here's a possible revamp for httpGet() based on feedback in #7090:
// Use .then() to draw a circle when the earthquake data loads.functionsetup(){letdata=httpGet("https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&limit=1&orderby=time");data.then(drawEarthquake);}functiondrawEarthquake(earthquakes){background(200);letearthquakeMag=earthquakes.features[0].properties.mag;letearthquakeName=earthquakes.features[0].properties.place;circle(width/2,height/2,earthquakeMag*10);textAlign(CENTER);text(earthquakeName,0,height-30,width,30);}
// Use .catch() to handle a loading error.functionsetup(){letdata=httpGet("https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&limit=1&orderby=time");data.then(drawEarthquake).catch(logError);}functiondrawEarthquake(earthquakes){background(200);letearthquakeMag=earthquakes.features[0].properties.mag;letearthquakeName=earthquakes.features[0].properties.place;circle(width/2,height/2,earthquakeMag*10);textAlign(CENTER);text(earthquakeName,0,height-30,width,30);}functionlogError(error){console.error("🆘",error);}
Note: This already works.
Parallelism
There's an open question about the best way to handle parallelism. preload() currently manages this with magic, which is nice. A proposed solution for async/await would use Promse.all() behind the scenes and return an array:
This optimization probably isn't needed for iterative work, but it's definitely helpful for sharing sketches. My sense is that beginners are usually ready for arrays by the time they need to draw a litter of kittens.
Pros (updated based on community comments)
Consistency: TBD
Readability: TBD
Cons (updated based on community comments)
TBD
Proposal status
Under review
The text was updated successfully, but these errors were encountered:
@limzykenneth oops, definitely worth clarifying. I thought it might be helpful to lightly decouple the discussion about async setup() and preload() from a discussion about keeping callbacks or fully adopting Promises (i.e., .catch() and .error()). They're closely related, but the latter hasn't really been addressed in #6767. So, I created a space for it.
I guess to clarify, callbacks for non-asynchronous cases (e.g. arrays) and ones without a single event to listen to (e.g. DOM event listeners) are still the standard. For all cases where promises are appropriate (asynchronous and involve waiting on a single future event) it seems that core js APIs have moved to promises.
Increasing access
Asynchronous JavaScript can be confusing, especially for beginners. A simple, consistent, and standard programming model could help to smooth out everyone's learning curve.
Which types of changes would be made?
Most appropriate sub-area of p5.js?
What's the problem?
p5.js' asynchronous programming model currently uses callbacks. It works, but most of the JavaScript ecosystem has migrated to Promises because they're easier to reason about, especially when used with async/await.
What's the solution?
I suggest that we use Promises and async/await consistently across the API. Most asynchronous functions uses Promises internally, so the implementation would probably be straightforward.
Here's an example of loading an image based on feedback in #6767:
And here's a possible revamp for
httpGet()
based on feedback in #7090:Note: This already works.
Parallelism
There's an open question about the best way to handle parallelism.
preload()
currently manages this with magic, which is nice. A proposed solution for async/await would use Promse.all() behind the scenes and return an array:Or:
Or, treading lightly here:
This optimization probably isn't needed for iterative work, but it's definitely helpful for sharing sketches. My sense is that beginners are usually ready for arrays by the time they need to draw a litter of kittens.
Pros (updated based on community comments)
Cons (updated based on community comments)
TBD
Proposal status
Under review
The text was updated successfully, but these errors were encountered: