前端面试必考题: Promise

这篇文章会是参考这篇文章,并且浓缩出重点,最后也会有几题测验,方便验收学习状况,那么我们进入今天的文章: Promise

什么是 Promise?

Promise 通常会由 「生产者代码」(producing code) 跟 「消费者代码」(consuming code) 组成

生产者代码 (producing code)

通过网路加载数据的程式码,例如: 餐厅

消费者代码 (consuming code)

想要在"生产者代码"完成工作的第一时间就能获得其工作成果的程式码,例如: 顾客


生产者代码 - Promise 对象的构造器 (constructor)

let promise = new Promise(function(resolve, reject) {  // executor});

传递给 new Promise 的函数被称为 executorexecutor 会在 new Promise 被创立时,自动执行

这边可以看到有 resolvereject 两个参数,分别代表成功或失败

resolve(value)reject(error)

new Promise 除了会有 result (resolve 或是 reject),还有 state ,代表该 Promise 的执行状态

预设会是 pending ,resolve 被调用时变为 fulfilled,或者在 reject 被调用时变为 rejected

任何一个 resolvedrejected 的 promise 都会被称为 settled

这只能有一个结果或一个 error

let promise = new Promise(function(resolve, reject) {  resolve("done");  reject(new Error("…")); // 被忽略  setTimeout(() => resolve("…")); // 被忽略});

这边想说明的是不管是 resolve 还是 reject,任何一个被触发后,就会跳脱出 Promise,所以后面的 resolve 或是 reject,就会被省略掉

state 和 result 都是内部的

刚刚有提到的 state 和 result 都只存活在该 Promise 中,一但离开了 Promise ,将不复存在,不过我们可以透过 .then().catch() 去接收 result


消费者代码

.then()

p.then(onFulfilled, onRejected);

.then() 接受两个参数,分别是 Promise 在成功及失败情况时的回呼函式。

let promise = new Promise(function(resolve, reject) {  setTimeout(() => resolve("done!"), 1000);});promise.then(  result => alert(result),  error => alert(error));

.catch()

.catch() 只会抓取 错误 (reject) 的 result

如果只对于错误 result 有兴趣,有两种方法

p.then(null, errorHandlingFunction) // 将 onFulfilled 设定为 nullp..catch(errorHandlingFunction)

.finally()

finally 的功能是设置一个处理程式在前面的操作完成后,执行清理/终结。
finally 的执行时间是在 promise settled 时就会执行:无论 promise 的result 是 resolve 还是 reject。


小试身手

这边分享四题我觉得还不错的考题,给各位读者做练习

请说明 console 出来的顺序
const promise = new Promise((resolve, reject) => {    console.log(1)    resolve()    console.log(2)})promise.then(() => {    console.log(3)})console.log(4)

答案:

1 -> 2 -> 4 -> 3

原因是因为 Promise 构造函数是同步执行的,promise.then 中的函数是异步执行的

请说明 console 出来的顺序,这题比较常,不过感觉会是业界会考的题目
const first = () => (new Promise((resolve, reject) => {    console.log(3);    let p = new Promise((resolve, reject) => {        console.log(7);        setTimeout(() => {            console.log(5);            resolve(6);        }, 0)        resolve(1);    });    resolve(2);    p.then((arg) => {        console.log(arg);    });}));first().then((arg) => {    console.log(arg);});console.log(4);

答案:

3 -> 7 -> 4 -> 1 -> 2 -> 5

相信大家基本上都能答出 3 -> 7 -> 4 ,至于后面的 1 -> 2 -> 5 是因为 setTimeout 是一个 Macrotask 他会先被放到 task queue 中,等待 Microtask 都执行完成才会被丢到 call stack 中执行
如果不清楚 macrotask 跟 microtask 的读者,可以参考我之前的文章

请问下方程式码会 console 出什么东西?
const promise = new Promise((resolve, reject) => {  resolve('success1')  reject('error')  resolve('success2')})promise  .then((res) => {    console.log('then: ', res)  })  .catch((err) => {    console.log('catch: ', err)  })

答案:

then: success1

原因是因为 Promise 中的 resolve 或 reject 只有第一次执行有效,所以后面的都会被省略
4. 请问下方程式码会 console 出什么?

Promise.resolve(1)  .then((res) => {    console.log(res)    return 2  })  .catch((err) => {    return 3  })  .then((res) => {    console.log(res)  })

答案:

1 2

原因是因为 Promise 可以链式调用。
Promise 每次调用 .then 或者 .catch 都会返回一个新的 Promise,从而实现了链式调用。
至于不是 1 3 的原因是因为是 resolve
可以想像成

Promise.resolve(1)  .then((res) => {    console.log(res)    return 2  })Promise.resolve(2)  .then((res) => {    console.log(res)  })

以上就是今天 Promise 的介绍,文章最后还是推荐各位读者可以去看看JavaScript.info 的文章

文章同步发布在我的 Medium ,有兴趣的读者可以去看看

以上就是今天的文章,如果有任何错误,或是问题都欢迎留言给我,那我们下次见,掰掰

参考文章:
https://javascript.info/promise-basics

https://medium.com/@123davidbill/macrotask-vs-microtask-%E5%B8%B8%E6%90%9E%E9%8C%AF%E7%9A%84%E9%83%A8%E5%88%86-236b7c2b8e8b


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章