01、Promise异步编程

Promise (IE🚫)是现代 JavaScript 中异步编程的基础,异步函数会启动操作并返回 Promise 对象(Promise /ˈprɒmɪs/ 承诺)。然后,你可以将处理函数附加到 Promise 对象上,当操作完成时(成功或失败),这些处理函数将被执行。

属性/方法 描述
静态属性/方法
Promise.all(iterable) 执行一个promise集合,都成功或有一个失败返回一个新promise对象(返回值的数组)
Promise.allSettled(iterable) 等到所有 promise 都已敲定,返回的promise包含返回值数组
Promise.any(iterable) 任意一个 promise 成功,就返回那个成功的 promise 的值。
Promise.race(iterable) 任意一个 promise 敲定,返回那个promise对象
Promise.reject(reason) 返回一个状态为已拒绝的 Promise 对象,并将给定的失败信息传递给对应的处理函数
Promise.resolve(value) 返回一个状态由给定 value 决定的 Promise 对象
构造函数
Promise(func(resolve, reject)) 创建一个 Promise 对象,用于包装一个不支持异步的普通函数,这里的函数是同步执行的
实例属性 内置属性,不可访问
[[PromiseState]]
- 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled):意味着操作成功完成。
- 已拒绝(rejected):意味着操作失败。
[[PromiseResult]] resolve返回的值,或reject返回的错误error。
实例方法
then(resolveFunc ,rejectFunc?) 添加成功和失败的回调函数,promise的状态决定调用哪个回调函数,参数2可空
catch(func(e)) 添加一个被rejected拒绝状态的回调函数,是**then**(null,rejectFunc)的简写版本
finally() 添加一个不管状态如何都会执行的回调,没有参数也没返回值,后面依然可以接then、catch

Promise/then

标准语法:

  1. // 标准语法
  2. let promise = new Promise(function (resolve, reject) {
  3. if (true) //根据需要返回成功、失败的状态。
  4. resolve("OK");
  5. else
  6. reject("failure"); //如果发现异常,会自动捕获并进行拒绝reject(error)处理
  7. });
  8. promise.then(successCallback, ?failureCallback)
  9. .catch(func)
  10. .finally(func);

Promise 的构造函数参数 **excutor** (function(resolve, reject))会自动运行。参数resolvereject是Promise提供的回调,在合适的地方调用他们即可,不过每次只有一个有效,他决定了promise的状态。

  • resolve(value) :如果任务成功完成并带有结果 value。
  • reject(error) :如果出现了 error,error 即为 error 对象。

🔸异步&微任务

  • Promise 的参数 **excutor**是同步的,会立即执行。
  • then、catch、finally都是异步的,他们是在一个promise准备就绪后,被放到一个微任务队列里(microtask queue),等当前JS的任务执行完毕后,才开始执行这个队列中的任务。注意不是多线程,还是在JS线程里。

    链式调用与异常

    then、catch、finally都会返回promise对象,所以它们可以被链式调用。
    *JavaScript异步 - 图1
    promise的异常处理

  • 隐式的**try...catch**,promise中的所有函数都包含一个隐式的try...catch,并对捕获的异常进行拒绝(rejection )处理。

  • 被拒绝的promise会找最近的 rejection 处理程序进行处理,如catch、then的的第二个参数。
  • 如果后面没人处理这个异常,会触发一个全局window的error—— unhandledrejection

    1. let promise = new Promise((resolve, reject) => { resolve("t0") });
    2. promise = Promise.resolve("t0"); //效果同上
    3. promise //链式调用
    4. .then(value => { return value + ' t1'; })
    5. .finally(() => console.log("休息一下!"))
    6. .then(value => { return value + ' t2'; })
    7. .then(value => { console.log(value) })
    8. .then(value => { throw new Error("着火了"); })
    9. .catch(err => { console.log(err) })
    10. .then(value => { console.log("继续处理" + value) })
    11. .finally(() => console.log("over"))
    12. // 休息一下!
    13. // t0 t1 t2
    14. // Error: 着火了
    15. // 继续处理undefined
    16. // over

    async/awit语法糖

    awitasync是使用Promise更简易的一种语法糖,完全可以代替Promise的语法形式。

  • async functionasync在函数申明前使用,让函数返回一个promise异步对象,同时允许函数内使用awit。

  • awit promise(func),只在async内部工作,awit会等待 promise(func)执行成,再继续往下。类似promise.then,他并不会阻塞CPU,是异步的。 ```javascript //async 修饰的函数返回值包装成一个promise async function doAsync() {
    1. return 1;
    2. return Promise.resolve(1); //效果同上
    } doAsync().then(console.log)

async function doAsync2(num) { try { //异常处理,同promise.catch let n = await ((num) => { return num + 1; })(num) n = await new Promise((resolve, reject) => { setTimeout(() => { resolve(n + 1); }, 1000); }) //等待返回结果,再往下执行 console.log(n); await (() => { console.log(“result:” + n) })(n); } catch (error) { console.log(error) } } doAsync2(1)

  1. <a name="Gs54m"></a>
  2. # 02、worker线程
  3. [**Worker**](https://developer.mozilla.org/zh-CN/docs/Web/API/Worker)(IE10)基于一个JS文件创建一个独立的线程,该JS文件代码运行在这个新线程中。该线程是独立于主线程的,其全局上下文不是window了,一般情况就是[DedicatedWorkerGlobalScope](https://developer.mozilla.org/zh-CN/docs/Web/API/DedicatedWorkerGlobalScope),用`self`来访问,**重点**是不能访问 DOM(窗口、文档、页面元素等等)。
  4. | **属性/方法** | **描述** |
  5. | --- | --- |
  6. | **构造函数** | |
  7. | [Worker](https://developer.mozilla.org/zh-CN/docs/Web/API/Worker/Worker)(jsUrl,options) | 创建一个专用 Web worker |
  8. | 实例**属性/方法** | |
  9. | [postMessage](https://developer.mozilla.org/zh-CN/docs/Web/API/Worker/postMessage)(message) | 将信息发送回生成它的线程; |
  10. | terminate() | 立即终止 worker,是立即 |
  11. | **事件** | |
  12. | [onmessage](https://developer.mozilla.org/zh-CN/docs/conflicting/Web/API/Worker/message_event)=func(message) | 订阅worker的消息,消息在`message.data`上 |
  13. | onerror=func(e) | 发生错误的异常事件 |
  14. | onmessageerror=func() | 消息解析错误的异常事件 |
  15. **🔸操作步骤**:<br />1、创建处理`worker`线程任务的JS文件,在JS文件中订阅消息事件用于接收消息指令<br />2、基于该指定的JS文件创建worker线程,该JS文件代码会被执行。<br />3、订阅worder的消息通知,接收worker发送过来的结果。<br />4、给worker发送消息(指令),让他干活。<br />5、worker收到的指令,并根据指令干活,干完后发送消息回去。
  16. ```javascript
  17. //1、创建处理worker线程任务的JS文件,在JS文件中订阅消息事件用于接收消息指令
  18. //***********JS文件***************//
  19. addEventListener("message", message => {
  20. console.log(message);
  21. //5、worker收到的指令,并根据指令干活,干完后发送消息回去。
  22. if(message.data.command==""){
  23. //do something
  24. postMessage("干完了");
  25. }
  26. })
  27. //***********主脚本***************//
  28. //2、基于该指定的JS文件创建worker线程,该JS文件代码会被执行。
  29. const worker = new Worker("../tstudy/js/js1.js");
  30. //3、订阅worder的消息通知,接收worker发送过来的结果。
  31. worker.onmessage = function (message) {
  32. console.log(message.data);
  33. }
  34. //4、给worker发送消息(指令),让他干活。
  35. worker.postMessage({ command: "generatPrimes", quote: 1000 });