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
标准语法:
// 标准语法
let promise = new Promise(function (resolve, reject) {
if (true) //根据需要返回成功、失败的状态。
resolve("OK");
else
reject("failure"); //如果发现异常,会自动捕获并进行拒绝reject(error)处理
});
promise.then(successCallback, ?failureCallback)
.catch(func)
.finally(func);
Promise 的构造函数参数 **excutor** (function(resolve, reject))
会自动运行。参数resolve
、reject
是Promise提供的回调,在合适的地方调用他们即可,不过每次只有一个有效,他决定了promise的状态。
- resolve(value) :如果任务成功完成并带有结果 value。
- reject(error) :如果出现了 error,error 即为 error 对象。
🔸异步&微任务:
- Promise 的参数
**excutor**
是同步的,会立即执行。 then、catch、finally都是异步的,他们是在一个promise准备就绪后,被放到一个微任务队列里(microtask queue),等当前JS的任务执行完毕后,才开始执行这个队列中的任务。注意不是多线程,还是在JS线程里。
链式调用与异常
then、catch、finally都会返回promise对象,所以它们可以被链式调用。
promise的异常处理:隐式的
**try...catch**
,promise中的所有函数都包含一个隐式的try...catch
,并对捕获的异常进行拒绝(rejection )处理。- 被拒绝的promise会找最近的 rejection 处理程序进行处理,如catch、then的的第二个参数。
如果后面没人处理这个异常,会触发一个全局window的error—— unhandledrejection。
let promise = new Promise((resolve, reject) => { resolve("t0") });
promise = Promise.resolve("t0"); //效果同上
promise //链式调用
.then(value => { return value + ' t1'; })
.finally(() => console.log("休息一下!"))
.then(value => { return value + ' t2'; })
.then(value => { console.log(value) })
.then(value => { throw new Error("着火了"); })
.catch(err => { console.log(err) })
.then(value => { console.log("继续处理" + value) })
.finally(() => console.log("over"))
// 休息一下!
// t0 t1 t2
// Error: 着火了
// 继续处理undefined
// over
async/awit语法糖
awit、async是使用Promise更简易的一种语法糖,完全可以代替
Promise
的语法形式。async function:
async
在函数申明前使用,让函数返回一个promise
异步对象,同时允许函数内使用awit。- awit promise(func),只在
async
内部工作,awit
会等待promise(func)
执行成,再继续往下。类似promise.then
,他并不会阻塞CPU,是异步的。 ```javascript //async 修饰的函数返回值包装成一个promise async function doAsync() {
} doAsync().then(console.log)return 1;
return Promise.resolve(1); //效果同上
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)
<a name="Gs54m"></a>
# 02、worker线程
[**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(窗口、文档、页面元素等等)。
| **属性/方法** | **描述** |
| --- | --- |
| **构造函数** | |
| [Worker](https://developer.mozilla.org/zh-CN/docs/Web/API/Worker/Worker)(jsUrl,options) | 创建一个专用 Web worker |
| 实例**属性/方法** | |
| [postMessage](https://developer.mozilla.org/zh-CN/docs/Web/API/Worker/postMessage)(message) | 将信息发送回生成它的线程; |
| terminate() | 立即终止 worker,是立即 |
| **事件** | |
| [onmessage](https://developer.mozilla.org/zh-CN/docs/conflicting/Web/API/Worker/message_event)=func(message) | 订阅worker的消息,消息在`message.data`上 |
| onerror=func(e) | 发生错误的异常事件 |
| onmessageerror=func() | 消息解析错误的异常事件 |
**🔸操作步骤**:<br />1、创建处理`worker`线程任务的JS文件,在JS文件中订阅消息事件用于接收消息指令<br />2、基于该指定的JS文件创建worker线程,该JS文件代码会被执行。<br />3、订阅worder的消息通知,接收worker发送过来的结果。<br />4、给worker发送消息(指令),让他干活。<br />5、worker收到的指令,并根据指令干活,干完后发送消息回去。
```javascript
//1、创建处理worker线程任务的JS文件,在JS文件中订阅消息事件用于接收消息指令
//***********JS文件***************//
addEventListener("message", message => {
console.log(message);
//5、worker收到的指令,并根据指令干活,干完后发送消息回去。
if(message.data.command==""){
//do something
postMessage("干完了");
}
})
//***********主脚本***************//
//2、基于该指定的JS文件创建worker线程,该JS文件代码会被执行。
const worker = new Worker("../tstudy/js/js1.js");
//3、订阅worder的消息通知,接收worker发送过来的结果。
worker.onmessage = function (message) {
console.log(message.data);
}
//4、给worker发送消息(指令),让他干活。
worker.postMessage({ command: "generatPrimes", quote: 1000 });