function sendPicture(id) {
user = db.find({userid: id});
picture = fs.readFile(user.picFile);
socket.write(picture);
console.log("done!")
}
db.find({userid: id}, callback);
db.find()
returns immediately (no blocking)callback
is invoked when the database object is readycallback
callback
can perform actions with the objectSynchronous | Asynchronous |
---|---|
user = db.find({userid: id}); |
db.find({userid: id}, callback); |
|
|
|
|
|
|
function sendPicture(id) {
db.find({userid: id}, callback1);
}
function callback1(err, user) {
fs.readFile(user.picFile, callback2);
}
function callback2(err, picture) {
socket.write(picture, callback3);
}
function callback3() {
console.log("done!");
}
function sendPicture(id) {
db.find({userid: id}, (err, user) => {
fs.readFile(user.picFile, (err, picture) => {
socket.write(picture, () => {
console.log("done!");
})
})
})
}
async
/await
(ECMAScript 2017)let prom = db.find({userid: id});
prom.then(fulfillCallback[, rejectCallback]);
then()
fulfillCallback
is called with “result of operation”rejectCallback
is called with “error value”function sendPicture(id) {
let prom1 = db.find({userid: id});
let prom2 = prom1.then(user => fs.readFile(user.picFile));
let prom3 = prom2.then(picture => socket.write(picture));
}
then()
returns a new promiseprom2
callback will be called after prom1
callback is completed
picture => socket.write(picture)
will be called afteruser => fs.readFile(user.picFile)
is completedfunction sendPicture(id) {
let prom1 = db.find({userid: id});
let prom2 = prom1.then(user => fs.readFile(user.picFile));
let prom3 = prom2.then(picture => socket.write(picture));
let prom4 = prom3.then(() => console.log("done!"));
}
sendPicture()
function itself returns immediatelyfunction sendPicture(id) {
let prom1 = db.find({userid: id});
let prom2 = prom1.then(user => fs.readFile(user.picFile));
let prom3 = prom2.then(picture => socket.write(picture));
let prom4 = prom3.then(() => console.log("done!"));
}
Or more succinctly,
function sendPicture(id) {
db.find({userid: id})
.then(user => fs.readFile(user.picFile))
.then(picture => socket.write(picture))
.then(() => console.log("done!"));
}
let prom1 = db.find({userid: id});
let prom2 = prom1.then(fulCB1, rejCB1);
let prom3 = prom2.then(fulCB2, rejCB2);
prom1
is settled?db.find()
prom1
is fulfilled to the output. fulCB1()
is called with “db object.”prom1
is rejected to error. rejCB1()
is called with error.let prom1 = db.find({userid: id});
let prom2 = prom1.then(fulCB1, rejCB1);
let prom3 = prom2.then(fulCB2, rejCB2);
prom2
be settled?fulCB1
or rejCB1
).prom2
is fulfilled to the value. fulCB2(value)
is called.prom2
is rejected to the error. rejCB2(error)
is called.let prom1 = db.find({userid: id});
let prom2 = prom1.then(fulCB1, rejCB1);
let prom3 = prom2.then(fulCB2, rejCB2);
p
?
let prom2 = prom1.then(user => fs.readFile(user.picFile));
p
is fulfilled to value
, prom2
is fulfilled to value
. fulCB2(value)
is called.p
is rejected to error
, prom2
is rejected to error
. rejCB2(error)
is called.function sendPicture(id) {
db.find({userid: id})
.then(user => fs.readFile(user.picFile))
.then(picture => socket.write(picture))
.then(() => console.log("done!"))
.catch(errorHandler);
}
then()
then()
then(null, rejectCB)
can be abbreviated to catch(rejectCB)
throw
an error in the callback, andcatch()
db.find({userid: id})
.then(user => {
if (!user.picFile) throw new Error("No picture!");
else return fs.readFile(user.picFile);
})
.then(picture => socket.write(picture))
...
.catch(err => console.log(err.message));
try
and catch
blockthen()
even after the success/failure of the asynchronous operation will be calledcallback
require('fs').promises
util.promisify()
val
:Promise.resolve(val)
err
:Promise.reject(err)
val
or rejected to err
depending on cond
:new Promise((resolve, reject) => {
...
if (cond) {
resolve(val);
} else {
reject(err);
}
})
Promise
with constructorresolve(val)
if successreject(err)
if failureasync
/await
(ECMAScript 2017)async function sendPicture(id) {
try {
user = await db.find({userid: id});
picture = await fs.readFile(user.picFile);
await socket.write(picture);
console.log("done!");
} catch (e) {
throw new Error("Cannot send the picture!");
}
}
await
can be used
async
functionasync
Functionasync function sendPicture(id) {
...
if (cond) {
return val;
} else {
throw new Error("Error!");
}
}
async
to function declaration “promisifies” the function
async
function returns a promise, not val
from return val
await
Keyworduser = await db.find({userid: id});
await
can be used in front of (a function that returns) a promise
try/catch
)await
keyword can be used only inside async
functionasync
/await
(1)async function sendPicture(id) {
try {
user = await db.find({userid: id});
picture = await fs.readFile(user.picFile);
await socket.write(picture);
console.log("done!");
} catch (e) {
throw new Error("Cannot send the picture!");
}
}
async
/await
makes asynchronous program look almost like synchronous program!await
makes an asynchronous function call “synchronous”
async
/await
(2)async function sendPicture(id) {
try {
user = await db.find({userid: id});
picture = await fs.readFile(user.picFile);
await socket.write(picture);
console.log("done!");
} catch (e) {
throw new Error("Cannot send the picture!");
}
}
async
converts any function to be “asynchronous”
sendPicture()
is returned immediately with a promisesendPicture()
like a synchronous program, but the call to sendPicture()
is nonblocking!await
in Top Block (1)await
in the outer most block, not in a function?user = await db.find({userid: 'john'});
picture = await fs.readFile(user.picFile);
await socket.write(picture);
console.log("done!");
await
can be used only in a async
function, but they are not in a function!await
in Top Block (2)async
function and call it(async () => {
user = await db.find({userid: 'john'});
picture = await fs.readFile(user.picFile);
await socket.write(picture);
console.log("done!");
})();
await
(1)function doubleAfter2Seconds(x) {
return new Promise((resolve, reject) => setTimeout(resolve, 2000, x*2));
}
async function addAsync(x) {
return await doubleAfter2Seconds(x)
+ await doubleAfter2Seconds(x)
+ await doubleAfter2Seconds(x);
}
addAsync(10).then(v => console.log(v));
await
(2)async function addAsync(x) {
const a = doubleAfter2Seconds(x);
const b = doubleAfter2Seconds(x);
const c = doubleAfter2Seconds(x);
return await a + await b + await c;
}
addAsync(10).then(v => console.log(v));
async
/await
(ECMAScript 2017)