Table of Contents generated with DocToc
- This code runs on the client side in the browser (aka the browser runs the JS code).
npm run start
runs the application in development mode using Webpack dev server.
- In your terminal run
npm install
to install all the repo dependencies. - Then run
npm run start
to start the app. This script deletes Webpack generateddist/
folder and then uses Webpack to regenerate it again. - Open a browser and go to
http://localhost:9871/
. The page will appear empty. Open up Chrome Dev Tools (right click and selectinspect
). Then click on theConsole
tab in Chrome Dev Tools. The data dump will appear in the console.
The project will start running on port 9871. If you want to change the port
open webpack.config.js
and find the port:9871
and change it from there.
module.exports = {
...
devServer: {
static: {
directory: path.join(__dirname,
"dist"
)
},
compress: true,
port: 9871
}
}
npm run test
if you want to run one test.npm run test-watch
if you want to keep running the tests.
In order to be able to use top level await
in index.ts
you have to do 2
things:
- Webpack: Set
futureDefaults: true
insideexperiments
in Webpack config file.
More info on it on Webpack docs.
webpack.config.js
module.exports = {
//...
experiments: {
futureDefaults: true,
},
};
- TypeScript: In
tsconfig.json
file change target to ES2017 and module ESNext.
{
...
"compilerOptions": {
"target": "ES2017",
"module": "ESNext",
...
}
}
This repo shows many ways you can make and unwrap promises. Check out index.ts
. Uncomment the functions on index.ts
to see how to make Promises and
their outcomes.
main1();
// await main2();
// await main3();
// await main4();
- Promise is a JavaScript's standard built-in object. Find out other standard built-in objects on MDN.
- Promise object has methods like reject(), resolve(), race() etc. we can call to do different things with the returned promise.
- Promises have two sections to think about:
- Promise creation/production
- Promise unwrapping/consuming
- Promise creation uses things like
new Promise()
,Promise.resolve()
,Promise.reject()
.
- Promise consumption uses things like
async/await
,.then()
,try/catch/finally blocks
- Why do we need Promises?
- Example of how to wrap html script loading inside a Promise
-
You can unwrap Promises using
.then()
-
You can unwrap Promises using
async/await
syntax. -
Both of these happen when Promise is being unwrapped stage (not at the Promise creation stage).
-
To make a Promise use
new Promise()
constructor. It takes an executor function. An executor function takes two functions as arguments: resolveFn and rejectFn. -
If you only care about successful Promise completions, omit the rejectFn.
-
If you only are about the rejected Promise completions, write (_, rejectFn).
-
If you don't wrap resolveFn and/or rejectFn into
setTimeout()
function, the Promises will return immediately. The resolveFn will return a Promise that has a state "fulfilled" and rejectFn will return a Promise that has a state "rejected".
const promise = new Promise((resolveFn, rejectFn) => {
// If you only care about successful Promise completions:
resolveFn(payloadToReturn) // you can also wrap this into setTimeout(). resolveFn()/resolve() is provided by the Promise constructor.
// If you only care about errored out Promise completions:
rejectFn("error message to return") // rejectFn()/reject() is provided by the Promise constructor.
// -------------------------------------
// Want to imitate a network call? Wrap resolveFn or rejectFn into setTimeout()
setTimeout(() => resolveFn(payloadToReturn), 2000);
})
resolveFn()
andrejectFn()
are methods on the Promise object.
- resolveFn(value/payload) is called when the Promise is resolved.
- From the Promise src docs: resolveFn(value) takes one argument
value
(I referred to value aspayloadToReturn
in the above sample code) with typeT | PromiseLike<T>
. You can read more details by pressingMod + b
on the Promise on your keyboard (this doesn't work for everyone. This is my keyboard configuration).
- rejectFn(reason) is called when the Promise is rejected.
- rejectFn(reason) takes a single argument
reason
with typeany
.
- We can use Promise.resolve() and Promise.reject() methods.
- Promise.resolve(payload)
PromiseState
will be immediately "fulfilled" andPromiseResult
will be the payload.
- Promise.reject("error message" or new Error("error message"))
PromiseState
will be immediately "rejected" andPromiseResult
will be the error message.
- As mentioned above there are two ways to consume Promises:
async/await
or/and.then()
async/await
- Firstly, we make a promise. Check out the
main4()
function inindex.ts
file.
const promiseIMade = new Promise(executorFn)
-
promiseIMade
returns a type Promise. Remember this pattern: when we have a promise, we have to unwrap it to get the value. But we can only unwrap a Promise that has changed it'sPromiseState
from "pending" to "fulfilled" or "rejected". -
We need to wait for the Promise state to change. That's when we use the
await
keyword.
const unwrappedPromise = await promiseIMade
- If the promise fulfilled, then we can use
unwrappedPromise
value. If the promise got rejected, we can do something with the error we got.
- Note: the error we get comes from the
rejectFn()
that we write inexecutonFn
we passed tonew Promise(executorFn)
when we made the Promise in the first place.
- allSettled() will return an array of Promises. Promises can either resolve or reject.
- This is a fast way to fetch for data parallel!!!