用 JavaScript 语言写的应用里会有一些异步(Asynchronous)的动作,就是执行这些动作的时候不能马上得到结果,这个动作需要点时间。处理应用里的这些异步的行为有几种方法,比如可以使用回调函数(Callback),可以使用 Promise,也可以用 async 函数。
Callback
定义一个函数的时候可以让这个函数支持使用一个函数参数,这个函数参数就是 Callback,也就是回调。使用这个函数的时候可以给它提供一个函数参数,也可以说给它一个 “回调”。
示例:
const nature = callback => {
const data = '🌳';
callback(data);
};上面用箭头函数的形式定义了一个叫 nature() 的函数,这个函数支持一个 callback 参数,这个参数应该是个函数,这里我叫它 callback,其实任何名字都是可以的。在 nature() 函数的内部执行了一下它的 callback 这个函数参数,执行的时候给它提供了一个 data 参数,这个 data 就是这个回调函数的参数。
nature(data => {
console.log(data);
});
// 在控制台上会输出 -> 🌳在使用 nature() 这个函数的时候,我们可以给它提供一个函数参数,也就是给它提供一个回调函数,这个回调支持一个参数,这个参数就是 data,当然你在这个回调里可以任意修改这个参数的名字。在这个回调函数的内部我们可以利用这个 data 参数去做一些事情,这里就是在控制台输出了这个 data 的值。所以这里执行这个 nature() 函数的结果就是在控制台上输出了一个:🌳
Promise
在应用里做的事情很多时候我们不能立即拿到结果,比如让应用从数据仓库里调取一组数据,这需要花点时间,应用向数据仓库发出指令调取数据,数据仓库服务要处理一下,完成以后才能把应用需要的数据交给应用。再比如在应用里需要请求一个外部服务接口,要等待外部接口发回来的响应的结果。如果同步执行这些动作,应用会卡住,等待处理的结果,拿到结果以后才能去做其它的事情。或者我们也可以异步完成这些事情,这样应用可以继续去做其它的事情。
Promise 就是在 JavaScript 语言里提供的一些处理异步动作的方法。比如你想异步完成一些事情,可以制造一个 Promise。就是你让应用去做一些事情,因为不能马上得到结果,所以只能先拿到一个承诺,这个承诺在未来可能会被兑现,也可能被拒绝。我们可以事先设计好当承诺兑现的时候要做什么,在承诺被拒绝以后要做什么。
示例:
const nature = () => {
return new Promise((resolve, reject) => {
resolve('🦖');
});
};上面定义了一个叫 nature() 的函数,这个函数里面会制造返回一个 Promise。在制造这个 Promise 的时候给它提供一个函数参数,这个函数参数可以有两个参数,resolve 还有 reject。它们两个是回调函数,成功兑现就执行 resolve() 带着结果,失败就在这个 Promise 里执行 reject() 带着错误。
在这个给 Promise 提供的函数参数的内部,可以去做一些异步的动作,比如去调取数据仓库里的数据,请求外部服务接口等等。当成功完成了这些事情以后,就可以执行一下 resolve() 这个函数,把结果交给这个 resolve() 。为了减少干扰,这里我们直接把一只 🦖 交给 resolve(),这只 🦖 就是这个 Promise 最终产生的数据。
nature() 这个函数会返回一个 Promise ,执行这个函数的时候可以这样做:
nature().then(data => {
console.log(data);
});
// 在控制台上会输出 -> 🦖先执行 nature() 函数,接着再用一个 .then(),在这个函数里可以设计一下当承诺成功兑现之后要做的事情,给这个 .then() 提供一个回调参数,这个回调支持一个 data 参数,这里这个 data 就是 Promise 最终生产出来的数据,也就是在 Promise 里面,交给 resolve() 函数的值。
模拟异步动作
如果你想模拟一下异步动作,可以使用 setTimeout(),它可以设置在规定的时间结束以后再执行指定的动作。
示例:
const nature = () => {
console.log('...');
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('🦖');
}, 2000);
});
};
nature().then(data => {
console.log(data);
});
console.log('🌋');
// 在控制台上会输出:
...
🌋
🦖
async 函数
用 async 关键词可以定义异步函数,这种异步函数可以简化 Promise 的使用。
示例:
const demo = async () => {
const data = await nature();
console.log(data);
};
demo();
// 在控制台上会输出:
...
🦖定义 demo() 这个函数的时候用了 async 这个关键词,这样它就会是一个异步函数,在函数里面可以使用 await 这个关键词等待执行异步动作。比如我们在 demo() 这个函数里,执行 nature() 函数的前面,用了 await,这个 nature() 就是在练习 Promise 的时候创建的一个函数,函数会返回一个 Promise,所以可以在它的前面用 await ,等这个 Promise 最终生产出来数据以后,把这个数据交给 data,在 demo() 函数里,我们可以利用这个 data 的值,比如在控制台上输出它。



