想象一下,你是一位顶尖歌手,粉丝没日没夜地询问你下个单曲什么时候发。
为了从中解放,你承诺(promise)会在单曲发布的第一时间发给他们。你给了粉丝们一个列表。他们可以在上面填写他们的电子邮件地址,以便当歌曲发布后,让所有订阅了的人能够立即收到。即便遇到不测,例如录音室发生了火灾,以致你无法发布新歌,他们也能及时收到相关通知。
每个人都很开心:你不会被任何人催促,粉丝们也不用担心错过单曲发行。
这是我们在编程中经常遇到的事儿与真实生活的类比:
- “生产者代码(producing code)”会做一些事儿,并且会需要一些时间。例如,通过网络加载数据的代码。它就像一位“歌手”。
- “消费者代码(consuming code)”想要在“生产者代码”完成工作的第一时间就能获得其工作成果。许多函数可能都需要这个结果。这些就是“粉丝”。
- Promise 是将“生产者代码”和“消费者代码”连接在一起的一个特殊的 JavaScript 对象。用我们的类比来说:这就是就像是“订阅列表”。“生产者代码”花费它所需的任意长度时间来产出所承诺的结果,而 “promise” 将在它(译注:指的是“生产者代码”,也就是下文所说的 executor)准备好时,将结果向所有订阅了的代码开放。
这种类比并不十分准确,因为 JavaScipt 的 promise 比简单的订阅列表更加复杂:它们还拥有其他的功能和局限性。但以此开始挺好的。
Promise 对象的构造器(constructor)语法如下:
let promise = new Promise(function(resolve, reject) {
// executor(生产者代码,“歌手”)
});
传递给 new Promise 的函数被称为 executor。当 new Promise 被创建,executor 会自动运行。它包含最终应产出结果的生产者代码。按照上面的类比:executor 就是“歌手”。
它的参数 resolve 和 reject 是由 JavaScript 自身提供的回调。我们的代码仅在 executor 的内部。
当 executor 获得了结果,无论是早还是晚都没关系,它应该调用以下回调之一:
- resolve(value) — 如果任务成功完成并带有结果 value。
- reject(error) — 如果出现了 error,error 即为 error 对象。