回调函数是作为实参传入的函数。 这种编程模式会在同步和异步编程中形成一串函数调用。 编写回调函数与编写普通函数没有区别,不过回调函数必须与调用方函数定义的签名一致。
const squareLength = 5;
// Caller function takes a callback function
function applyToSquare(callback) {
return callback(squareLength);
}
// Callback must expect the possible argument from the calling function
function areaOfSquare(number) {
return number * number;
}
applyToSquare(areaOfSquare); // => 25
你也可以把回调写成函数表达式、匿名函数表达式或箭头函数表达式:
applyToSquare(function squarePerimeter(side) {
return side * 4;
});
applyToSquare(function (side) {
return side * 4;
});
applyToSquare((side) => {
return side * 4;
});
你正在为顾客创建一个新的在线门户,让他们可以直接从水果商那里订购新鲜水果。 水果商有一个 API,你可以用它来查看他们是否有顾客想要的库存。 你需要创建一个小型函数库,用来与水果商的 API 交互。
订单成功时,门户应该通知顾客。
定义一个onSuccess回调函数,当水果商的库存充足、订单因此成功时,这个函数会被调用。
这个函数应该调用导入的notify函数,并传入{ message: 'SUCCESS' },让顾客知道他们的订单已经成功。
onSuccess();
// => `notify` called with `{ message: 'SUCCESS' }`
订单失败时,门户应该通知顾客。
定义一个onError回调函数,当订单因为水果商_没有_库存中的水果或出现错误而失败时,这个函数会被调用。
这个函数应该调用导入的notify函数,并传入{ message: 'ERROR' },让顾客知道他们的订单没有成功。
onError();
// => `notify` called with `{ message: 'ERROR' }`
水果订单通过水果商 API 提供的order函数下单。
这个函数接收三个实参:一个查询,包含所需水果的variety和quantity;一个回调函数,在订单成功时被调用;还有一个回调函数,在订单遇到错误时被调用。
你希望让代码库免受潜在的外部改动影响,于是决定把对order函数的调用包装进一个名为orderFromGrocer的新函数中。
实现orderFromGrocer函数,尝试通过调用水果商 API 的order函数来下单,并确保把传入orderFromGrocer的实参转发给这次 API 调用。
查询的形式是一个对象:
const query = {
variety: string,
quantity: number,
};
orderFromGrocer(
{ variety: 'pear', quantity: 12 },
exampleSuccessCallback,
exampleErrorCallback,
);
// => `order` was called with the query and the callbacks
顾客现在可以通过你的门户下水果订单了,不过你发现自己在代码库的许多不同地方都在调用orderFromGrocer函数,每次都要把query和两个callback函数作为实参传进去。
你发现这是个重构代码的机会,觉得如果只要传入所需水果的variety和quantity就能下单,会简单得多。
定义postOrder辅助函数,它接收variety和quantity作为实参,并尝试向水果商下单。
postOrder('peach', 100);
// => order placed for 100 peaches