約束と手書きの約束の理解

導入

約束を理解する前に、まず基本的な部分を理解する必要があります。これは、コンピューターの原則、ブラウザーの原則、およびJSの実行の原則に分けられます。

コンピューターの原則

処理する

定義:プロセスは、CPUリソース割り当ての最小単位であり、独立したリソースです。

定義:スレッドはCPUスケジューリングの最小単位です-共有リソース

関連する質問

  1. Chromeは新しいウィンドウを開きますが、タブページはプロセスですか、それともスレッドですか?回答:プロセス
  2. プロセスはどのように通信しますか(ウィンドウはどのように通信しますか)?回答:ストレージ(localStorage、sessionStorage、cookie)
  3. さまざまなストレージの違いは?
  4. ブラウザの原則(主に中レベルおよび高レベルの管理)ブラウザには、プロセス内に複数のスレッドがあります

ブラウザの原則

GUIレンダリングエンジン

  1. html、cssを解析し、domツリーを構築する=>レイアウト=>描画する
  2. これはjsエンジンと相互に排他的です。JSエンジンスレッドが実行されると、GUIは保留になり、タスクキューがアイドル状態のときにGUIを実行し続けます。

JSエンジンスレッド

  1. JSを処理し、スクリプトを解析して実行します
  2. 実行するイベント、イベントキューの割り当て、処理、および実行
  3. GUIレンダリングのブロック

タイマーがエンジンをトリガーします

  1. setTimeout、setInterval
  2. jsエンジンによって割り当てられたタイマータスクを受け取り、それを数えます
  3. 処理が完了すると、イベントトリガースレッドに渡されてトリガーされます

非同期HTTPリクエストスレッド

  1. リクエストクラスの処理を非同期的に実行し、promise/ajaxなどを実行します。
  2. JSエンジンを受信して​​、非同期HTTPリクエストをディスパッチします
  3. コールバックをリッスンし、それをイベントトリガースレッドに渡してトリガーします

イベントトリガーエンジン

  1. 受信ソース:タイマー、非同期、ユーザーアクション
  2. コールバックイベントをタスクキューの最後に順番に接続し、エンジンに返します

JS実行原理

メモリを割り当てる

実行スタック

インタビューの質問1:jsスタックの実行順序、スタックオーバーフロー(スタックバースト)=>パフォーマンスの
最適化インタビューの質問2:配列操作の戻り値の問題スプライス分割... promise.allpromise.race

タスクキュー
マクロタスク:マクロ:スクリプト、setTimeout、setInterval、I / O
マイクロタスク:新しいpromise {}。then()

マイクロタスクがあり、マクロタスクは常にマイクロタスクに先行します

1.約束の深い理解

約束仕様

promise是一个有then方法的对象或者函数,promise有三种状态

状态
  1. pending: 初始状态 - 可改变
  2. fulfilled:最终状态 - 不可改变
  3. rejected:最终状态 - 不可改变
状态变化
  1. pending -> reslove(value) -> fulfilled
  2. pending -> reject(reason) -> rejected
then方法
  1. 参数:onFulfilledonRejected(两个参数必须是函数,如果不是函数,应该被忽略)
  2. onFulfilledonReject是微任务 (js是单线程,分为了同步任务和异步任务,而异步任务中也有优先级,微任务即表示优先级高的)
  3. then方法可以调用多次,用数组来存放多个onFulfilled的回调和onRejected的回调
  4. then方法的返回值是一个新的promise 将onFulfilled或onrejected的返回结果为x,通过resolvePromise来解析promise this.resolvePromise(promise2, x, resolve, reject);

2.一步步实现一个promise

  1. class对象并定义三种状态
  2. constructor中设置初始状态以及定义value和reason
  3. 实现resolve和reject方法,在状态为pending时改变状态
  4. constructor中传一个入参fn,fn接收resolve和reject,若报错则通过reject抛出去
  5. 实现then方法,接收两个参数:then(onFulfilled, onRejected) {}
  6. 检查处理then参数,判断onFulfilled和onRejected是否为函数,若不是函数,则返回value或reason
  7. 定义返回值(promise2)并根据当前promise的状态调用不同的函数
  8. 设置一个状态的监听机制, 当状态变成fulfilled或者rejected后, 再去执行callback
  9. 新建两个数组, 来分别存储成功和失败的回调, 调用then的时候, 如果还是pending就存入数组
  10. 实现getter和setter函数,在给status赋值后, 下面再加一行forEach
  11. 当 onFulfilled 或者 onRejected 抛出异常 e ,则 promise2 拒绝执行,并返回拒因 e。(这样的话, 我们就需要手动catch代码,遇到报错就reject)
  12. 当onFulfilled 或者 onRejected 返回一个值 x ,则运行resolvePromise方法。将realOnFulfilled(this.value)赋值给x,this.resolvePromise(promise2, x, resolve, reject);
  13. 实现resolvePromise方法
  14. onFulfilled 和 onRejected 是微任务,使用queueMicrotask包裹执行函数
  15. 实现catch方法

3.Iterator,Generator和async的理解

Interator迭代器
  1. 是一种的特殊的对象,每一个迭代器对象都有一个next方法,
  2. 每次调用都会返回一个劫夺对象,结果对象中包含两个值:
    value: 当前属性的值;
    done: 判断是否遍历结束
Generator生成器
  1. 生成器时一种返回迭代器的函数,函数中会用到新的关键字yield,使用function*来创建
function* generator() {
    const list = [1, 2, 3];
    for (let i of list) {
        yield i;
    }
}
let g = generator();
console.log(g.next()); // {value: 1, done: false}
console.log(g.next()); // {value: 2, done: false}
console.log(g.next()); // {value: 3, done: false}
console.log(g.next()); // {value: undefined, done: true}
复制代码
  1. 注意
  • 每当执行完一条yield语句后函数就会自动停止执行, 直到再次调用next();
  • yield关键字只可在生成器内部使用,在其他地方使用会导致程序抛出错误;
  • 可以通过函数表达式来创建生成器, 但是不能使用箭头函数
    let generator = function *(){}

4.面试中可能会遇到的问题

  1. 为什么promise resolve了一个value, 最后输出的value值确是undefined
const test = new MPromise((resolve, reject) => {
    setTimeout(() => {
        resolve(111);
    }, 1000);
}).then((value) => {
    console.log('then');
});

setTimeout(() => {
    console.log(test);
}, 3000)
复制代码

答:因为在.then中没有return则相当于return undefined,所以value是undefined

  1. 为什么在catch的回调里, 打印promise, 显示状态是pending
const test = new MPromise((resolve, reject) => {
    setTimeout(() => {
        reject(111);
    }, 1000);
}).catch((reason) => {
    console.log('报错' + reason);
    console.log(test)
});

setTimeout(() => {
    console.log(test);
}, 3000)
复制代码

答:catch函数会返回一个新的名为test的promise函数,在catch中还没有执行完成,所以是pending

おすすめ

転載: juejin.im/post/7080141138232868901