約束の面接の質問 テストのポイント

面接の質問と試験のポイント

Promiseの基本的な考え方

画像-20210618161125894

チェーンコールルール

画像-20210621103501094

画像-20210621103501094

  1. then メソッドは新しい Promise を返す必要があります

    次のように理解できます后续处理也是一个任务

  2. 新しいタスクのステータスは、その後の処理によって異なります。

    • 該当する後続処理がない場合、新規タスクのステータスは前のタスクと同じであり、データは前のタスクのデータです。

    • 後続の処理がまだ実行されていない場合、新しいタスクは一時停止されます。

    • 後続の処理が実行された場合、新しいタスクのステータスは後続の処理に基づいて決定されます。

      • 後続の処理はエラーなく実行され、新規タスクのステータスは完了し、データは後続処理の戻り値になります。
      • 後続の処理の実行にエラーがあり、新しいタスクのステータスは失敗し、データは例外オブジェクトです。
      • その後の実行後に返されるのはタスク オブジェクトであり、新しいタスクのステータスとデータはタスク オブジェクトと一致します。

静的メソッドを約束する

メソッド名 意味
Promise.resolve(データ) 完了したタスクを直接返します
約束.拒否(理由) 拒否ステータスのタスクを直接返す
Promise.all(タスク配列) タスク
配列を返します。すべてのタスクが成功した場合は成功し、
いずれかのタスクが失敗した場合は失敗します。
Promise.any(タスク配列) タスク
配列を返します。いずれかのタスクが成功した場合は成功し、
すべてのタスクが失敗した場合は失敗します。
Promise.allSettled(タスク配列) タスク
配列を返します。すべてのタスクが正常に解決された場合、
タスクは失敗しません。
Promise.race(タスク配列) タスクの
配列を返します。タスクが決定されている場合は、そのステータスと一致します。

非同期で待機する

Promise を使用すると、非同期タスクを処理するための統一された方法が得られます。

統一された処理方法により、ES 担当者は処理をさらに最適化できます。

ES7ではPromiseをよりエレガントに表現するためにasync2つのキーワードを導入await

非同期

async キーワードは関数を変更するために使用されます。このキーワードによって変更された関数は Promise を返す必要があります。

async function method1(){
    
    
  return 1; // 该函数的返回值是Promise完成后的数据
}

method1(); // Promise { 1 }

async function method2(){
    
    
  return Promise.resolve(1); // 若返回的是Promise,则method得到的Promise状态和其一致
}

method2(); // Promise { 1 }

async function method3(){
    
    
  throw new Error(1); // 若执行过程报错,则任务是rejected
}

method3(); // Promise { <rejected> Error(1) }

待つ

awaitキーワードは、特定の Promise が完了するまで待機することを意味し、関数で使用する必要があります。async

async function method(){
    
    
  const n = await Promise.resolve(1);
  console.log(n); // 1
}

// 上面的函数等同于
function method(){
    
    
  return new Promise((resolve, reject)=>{
    
    
    Promise.resolve(1).then(n=>{
    
    
      console.log(n);
      resolve(1)
    })
  })
}

await他のデータを待つこともできます

async function method(){
    
    
  const n = await 1; // 等同于 await Promise.resolve(1)
}

try-catch失敗したタスクを処理する必要がある場合は、次の構文を使用できます。

async function method(){
    
    
  try{
    
    
    const n = await Promise.reject(123); // 这句代码将抛出异常
    console.log('成功', n)
  }
  catch(err){
    
    
    console.log('失败', err)
  }
}

method(); // 输出: 失败 123

イベントループ

これまでに学んだことによると、イベントキューに入る関数は次のとおりです。

  • setTimeoutコールバック、マクロタスク
  • setIntervalコールバック、マクロタスク
  • Promisethen関数コールバック、マイクロタスク(マイクロタスク)
  • requestAnimationFrameコールバック、マクロタスク
  • イベントハンドリング関数、マクロタスク

面接の質問

  1. 次のコードの出力は何でしょうか?

    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 对象,并传入一个执行器函数作为参数。执行器函数立即执行,输出1。
    接着,调用 resolve() 方法,表示 Promise 对象的状态变为已解决(fulfilled)。然后输出2。
    然后,调用 promise.then() 方法注册一个回调函数,该回调函数会在 Promise 对象状态变为已解决时执行。此时,Promise 对象的状态已经是已解决,所以回调函数会立即执行,输出3。
    最后,输出4。
    总结:Promise 对象的执行是异步的,即使 Promise 对象的状态立即变为已解决,注册的回调函数也会在下一个事件循环中执行。因此,输出的顺序是1243
  2. 次のコードの出力は何でしょうか?

    const promise = new Promise((resolve, reject) => {
          
          
        console.log(1); 
        setTimeout(()=>{
          
          
          console.log(2)
          resolve(); 
          console.log(3);
        })
    })
    
    promise.then(() => {
          
          
        console.log(4);
    })
    
    console.log(5);
    // 1 5 2 3 4
    解释如下:
    
    首先,创建了一个 Promise 对象,并传入一个执行器函数作为参数。执行器函数立即执行,输出1。
    接着,执行器函数中调用 setTimeout() 方法,将其中的代码放入宏任务队列中,并设置一个延迟时间。此时,setTimeout() 方法中的代码不会立即执行,而是在延迟时间结束后才执行。
    然后,继续执行后续代码,输出5在延迟时间结束后,setTimeout() 方法中的代码开始执行。首先输出2,表示延迟时间结束后的第一个执行的任务。
    然后,调用 resolve() 方法,表示 Promise 对象的状态变为已解决(fulfilled)。
    接着,输出3。
    最后,注册在 promise.then() 方法中的回调函数会在 Promise 对象状态变为已解决时执行。此时,Promise 对象的状态已经是已解决,所以回调函数会立即执行,输出4。
    总结:由于 setTimeout() 方法中的代码被放入宏任务队列中,所以会在后续代码执行完毕后才执行。因此,输出的顺序是15234
  3. 次のコードの出力は何でしょうか?

    const promise1 = new Promise((resolve, reject) => {
          
          
    	setTimeout(() => {
          
          
        resolve()
      }, 1000)
    })
    const promise2 = promise1.catch(() => {
          
          
      return 2;
    })
    
    console.log('promise1', promise1) 
    console.log('promise2', promise2) 
    
    setTimeout(() => {
          
          
      console.log('promise1', promise1) 
      console.log('promise2', promise2) 
    }, 2000)
    // promise1 Promise {<pending>} promise2 Promise {<pending>}
    // promise1 Promise {<resolved>} promise2 Promise {<resolved>}
    解释如下:
    
    首先,创建了一个 Promise 对象 promise1,并在其执行器函数中使用 setTimeout() 方法设置了一个延迟时间为1秒的定时任务。在定时任务执行后,调用 resolve() 方法,将 promise1 的状态设置为已解决(fulfilled)。
    接着,创建了一个新的 Promise 对象 promise2,并使用 promise1.catch() 方法注册了一个错误处理回调函数。由于 promise1 的状态是已解决,所以错误处理回调函数不会执行。promise2 的状态与 promise1 相同。
    然后,输出 promise1 和 promise2 的值。由于 promise1 和 promise2 的状态都是待定(pending),所以输出为 Promise {
          
          <pending>}。
    在2秒后,执行第二个 setTimeout() 方法中的代码。此时,promise1 的状态已经是已解决,所以输出 promise1 的值为 Promise {
          
          <resolved>}。由于 promise2 是通过 promise1.catch() 方法创建的,并且没有发生错误,所以 promise2 的状态也是已解决,输出 promise2 的值为 Promise {
          
          <resolved>}。
    总结:在定时任务执行前,promise1 和 promise2 的状态都是待定(pending)。在定时任务执行后,promise1 的状态变为已解决(fulfilled),promise2 的状态与 promise1 相同。
    
  4. 次のコードの出力は何でしょうか?

    async function m(){
          
          
      console.log(0)
      const n = await 1;
      console.log(n);
    }
    //等价于
    function m(){
          
          
        console.log(0)
    	return Promise.resolve(1).then((n)=>{
          
          
            console.log(n)
        })
    }
    
    m();
    console.log(2);
    // 0 2 1
    现在让我们逐步解释每个输出:
    
    首先,代码开始执行,调用了 m() 函数,即 m();。这个函数调用会立即开始执行,但需要注意的是,m() 函数内部包含了一个 await 表达式 const n = await 1;,它会暂停函数的执行,直到 await 后面的表达式解决为 Promise,并等待 Promise 完成。在这里,await 1; 表示等待一个解决为 1 的 Promise,由于这是一个立即解决的 Promise,所以不会有延迟,函数会继续执行。然后,const n = 1; 将 n 设置为 1,但在这个点上,console.log(n); 还没有执行。
    
    接下来,console.log(2); 输出 2,因为此时程序继续执行,没有等待 m() 函数内部的异步操作完成。
    
    最后,console.log(n); 输出 1,因为在 m() 函数内部,n 的值已经被设置为 1
  5. 次のコードの出力は何でしょうか?

    async function m(){
          
          
      console.log(0)
      const n = await 1;
      console.log(n);
    }
    
    (async ()=>{
          
          
      await m();
      console.log(2);
    })();
    
    console.log(3);
    // 0 3 1 2
    现在让我们逐步解释每个输出:
    
    首先,代码开始执行,遇到了最外层的 console.log(3);。这行代码会立即执行,输出 3接下来,进入立即执行的自执行异步函数 (async () => {
          
           ... })();,它会立即开始执行。在函数内部,遇到 await m(); 这行代码,它调用了 m() 函数。然而,需要注意的是,m() 函数内部包含了一个 await 表达式 const n = await 1;,它会暂停函数的执行,直到 await 后面的表达式解决为 Promise,并等待 Promise 完成。在这里,await 1; 表示等待一个解决为 1 的 Promise,由于这是一个立即解决的 Promise,所以不会有延迟,函数会继续执行。然后,const n = 1; 将 n 设置为 1,并继续执行函数内部。
    
    console.log(n); 输出 1,因为此时 n 的值已经被设置为 1函数执行完毕后,继续执行 (async () => {
          
           ... })(); 后面的 console.log(2);,输出 2
  6. 次のコードの出力は何でしょうか?

    async function m1(){
          
          
      return 1;
    }
    
    async function m2(){
          
          
      const n = await m1();
      console.log(n)
      return 2;
    }
    
    async function m3(){
          
          
      const n = m2();
      console.log(n);
      return 3;
    }
    
    m3().then(n=>{
          
          
      console.log(n);
    });
    
    m3();
    
    console.log(4);
    // 4 1 3 1
    

    画像-20230914205348167

  7. 次のコードの出力は何でしょうか?

    Promise.resolve(1)	
      .then(2)// then里传的不是函数,就相当于可以把这个then给删了
      .then(Promise.resolve(3))// then里传的不是函数,就相当于可以把这个then给删了
      .then(console.log)
    //等价于
    Promise.resolve(1)	
      .then(console.log)
    // 1
    
  8. 次のコードの出力は何でしょうか?

    var a;
    var b = new Promise((resolve, reject) => {
          
          
      console.log('promise1');
      setTimeout(()=>{
          
          
        resolve();
      }, 1000);
    }).then(() => {
          
          
      console.log('promise2');
    }).then(() => {
          
          
      console.log('promise3');
    }).then(() => {
          
          
      console.log('promise4');
    });
    
    a = new Promise(async (resolve, reject) => {
          
          
      console.log(a);
      await b;
      console.log(a);
      console.log('after1');
      await a
      resolve(true);
      console.log('after2');
    });
    
    console.log('end');
    

    画像-20230914211331453

    画像-20230914210918609

  9. 次のコードの出力は何でしょうか?

    async function async1() {
          
          
        console.log('async1 start');
        await async2();
        console.log('async1 end');
    }
    async function async2() {
          
          
    	console.log('async2');
    }
    
    console.log('script start');
    
    setTimeout(function() {
          
          
        console.log('setTimeout');
    }, 0)
    
    async1();
    
    new Promise(function(resolve) {
          
          
        console.log('promise1');
        resolve();
    }).then(function() {
          
          
        console.log('promise2');
    });
    console.log('script end');
    // script start
    // async1 start
    // async2
    // promise1
    // script end
    // async1 end
    // promise2
    // setTimeout
    

おすすめ

転載: blog.csdn.net/qq_53461589/article/details/132918382