个人技术站点JASONWU

Keep Coding


  • 主页

  • 文章

  • 搜索

JavaScript 构建 Promise

新建: 2021-05-30 编辑: 2021-07-05   |   分类: JavaScript   | 字数: 1364 字

介绍 Promise

Promise
一个包含异步操作结果(将来结果)的占位符对象。

Promise 的优点:

  • 无需依赖将事件和回调传递给异步函数,就可以处理异步结果
  • 可为一系列异步操作提供 Promise 链式调用,从而避免回调地狱(Callback Hell)

Promise 生命周期:

  1. Pending:构建 Promise 对象时的初始状态,内部还是立即执行的同步代码
    • new Promise()
  2. Settled:异步任务执行完毕
    • Fulfilled:异步任务执行成功,且结果可用
      • then()
    • Rejected:异步任务执行失败,即发生了错误
      • then(onFulfilled[, onRejected]) 或 catch()

构建 Promise

Promise 是一个特殊的对象,接收一个执行器(executor)函数,其中执行器函数包含两个参数:

  1. resolve:代表处理成功时的回调函数
  2. reject:代表处理失败时的回调函数
JavaScript
 1const lotteryPro = new Promise((resolve, reject) => {
 2   if (Math.random() >= 0.5) {
 3      resolve('恭喜,您中奖啦!!!');
 4   } else {
 5      reject(new Error('很遗憾,您未中奖'));
 6   }
 7});
 8
 9lotteryPro
10  .then(res => console.log(res))
11  .catch(err => console.error(err.message));

此外,还可以使用 Promise.resolve 或 Promise.reject 来构建立即执行的 Promise。

JavaScript
1Promise.resolve('结果').then(res => console.log(res));
2
3Promise.reject(new Error('错误'))
4  .catch(err => console.error(err.message));

Promise ≠ 异步

Promise 不等于异步:Promise 不会也不能将同步代码转为异步代码,它的作用仅仅是包装异步代码,从而使调用异步变得更加优雅,并使之支持 async/await 关键字。

JavaScript
 1const startMilli = Date.now();
 2console.log(`1:开始执行`);
 3
 4// Promise 不能也不会将同步代码转换为异步代码
 5new Promise(resolve => {
 6  // 假设正在运行一段耗时代码
 7  const start = Date.now();
 8
 9  while (Date.now() - start <= 2000) {
10    // 模拟2秒耗时操作
11  }
12
13  resolve('2秒 Promise');
14})
15  .then(data => console.log(data));
16
17// 该代码会被阻塞至少2秒
18const duration = Math.trunc((Date.now() - startMilli) / 1000);
19console.log(`2:结束执行,耗时:${duration}秒`);
20
21// 1:开始执行
22// 2:结束执行,耗时:2秒
23// 2秒 Promise

Promisifying

Promisifying
将基于回调的异步代码转换为基于 Promise 的异步代码。

setTimeout

JavaScript
 1// 因为 `setTimeout` 不会返回错误,故只需要 `resolve` 即可
 2const wait = seconds =>
 3  new Promise(resolve => setTimeout(resolve, seconds * 1000));
 4
 5// 使用 Promisifying `setTimeout`
 6wait(1)
 7  .then(() => {
 8    console.log('1秒后执行');
 9
10    return wait(1);
11  })
12  .then(() => {
13    console.log('2秒后执行');
14
15    return wait(1);
16  })
17  .then(() => {
18    console.log('3秒后执行');
19
20    return wait(1);
21  })
22  .then(() => {
23    console.log('4秒后执行');
24
25    return wait(1);
26  });

回调地狱(Callback Hell):

JavaScript
 1setTimeout(() => {
 2  console.log('1秒后执行');
 3
 4  setTimeout(() => {
 5    console.log('2秒后执行');
 6
 7    setTimeout(() => {
 8      console.log('3秒后执行');
 9
10      setTimeout(() => {
11        console.log('4秒后执行');
12      }, 1000);
13    }, 1000);
14  }, 1000);
15}, 1000);

Geolocation

JavaScript
 1navigator.geolocation.getCurrentPosition(
 2  pos => console.log(pos),
 3  err => console.error(err.message)
 4);
 5
 6// Promisifying
 7const geoPro = new Promise((resolve, reject) => {
 8   navigator.geolocation.getCurrentPosition(resolve, reject);
 9});
10
11geoPro
12  .then(pos => console.log(pos))
13  .catch(err => console.error(err.message));
14
15console.log('获取位置');

DOM 加载图片

JavaScript
 1const body = document.querySelector('body');
 2
 3(() => {
 4  // DOM 加载图片是一个异步操作
 5  const img = document.createElement('img');
 6  img.src = 'qgs.png';
 7
 8  img.addEventListener('load', () => {
 9    body.insertAdjacentElement('afterbegin', img);
10  });
11})();
12
13// Promisifying
14const createImage = imgPath =>
15  new Promise((resolve, reject) => {
16    const img = document.createElement('img');
17    img.src = imgPath;
18
19    img.addEventListener('load', () => {
20      resolve(img);
21    });
22
23    img.addEventListener('error', () => {
24      reject(new Error('未找到图片'));
25    });
26  });
27
28createImage('j.png')
29  .then(img => {
30    body.insertAdjacentElement('afterbegin', img);
31  })
32  .catch(err => console.error(err.message));
33
34console.log('DOM 开始加载图片');
#Async# #Promise#

文章:JavaScript 构建 Promise

链接:https://www.wuxianjie.net/posts/js-async-promise/

作者:吴仙杰

文章: 本博客文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议,转载请注明出处!

HTTP 请求与响应报文格式
JavaScript 函数中的 this 值
  • 文章目录
  • 站点概览
吴仙杰

吴仙杰

🔍 Ctrl+K / ⌘K

27 文章
9 分类
25 标签
邮箱 GitHub
  • 介绍 Promise
  • 构建 Promise
  • Promise ≠ 异步
  • Promisifying
    • setTimeout
    • Geolocation
    • DOM 加载图片
© 2021-2025 吴仙杰 保留所有权利 All Rights Reserved
浙公网安备 33010302003726号 浙ICP备2021017187号-1
0%