Promise interview questions test points

Interview questions and test points

Basic concepts of Promise

image-20210618161125894

Chain call rules

image-20210621103501094

image-20210621103501094

  1. The then method must return a new Promise

    can be understood as后续处理也是一个任务

  2. The status of the new task depends on subsequent processing:

    • If there is no relevant subsequent processing, the status of the new task is the same as that of the previous task, and the data is the data of the previous task.

    • If there is subsequent processing but has not yet been executed, the new task is suspended.

    • If subsequent processing is executed, the status of the new task will be determined based on the subsequent processing.

      • The subsequent processing is executed without errors, the status of the new task is completed, and the data is the return value of the subsequent processing.
      • There is an error in the execution of subsequent processing, the status of the new task is failed, and the data is an exception object.
      • What is returned after subsequent execution is a task object, and the status and data of the new task are consistent with the task object.

Promise static methods

method name meaning
Promise.resolve(data) Directly returns a completed task
Promise.reject(reason) Directly return a task with a rejected status
Promise.all(task array) Returns a task
array. If all tasks are successful, it will succeed.
If any one fails, it will fail.
Promise.any(task array) Returns a task
array. If any task succeeds, it will succeed. If
all tasks fail, it will fail.
Promise.allSettled(task array) Returns a task
array. If all tasks are resolved successfully,
the task will not fail.
Promise.race(task array) Returns a task
array. If any task has been decided, the status is consistent with it.

async and await

With Promise, asynchronous tasks have a unified way to handle them.

With a unified processing method, ES officials can further optimize it.

ES7 introduces two keywords asyncand awaitto express Promise more elegantly

async

The async keyword is used to modify functions. The function modified by it must return 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

awaitThe keyword means waiting for a certain Promise to complete, it must be used asyncin the function

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)
    })
  })
}

awaitYou can also wait for other data

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

If you need to handle failed tasks, you can use try-catchthe syntax

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

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

event loop

According to what I have learned so far, the functions that enter the event queue are as follows:

  • setTimeoutcallback, macro task
  • setIntervalcallback, macro task
  • Promise thenfunction callback, micro task (micro task)
  • requestAnimationFramecallback, macro task
  • Event handling function, macro task

Interview questions

  1. What is the output of the following code?

    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. What is the output of the following code?

    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. What is the output of the following code?

    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. What is the output of the following code?

    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. What is the output of the following code?

    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. What is the output of the following code?

    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
    

    image-20230914205348167

  7. What is the output of the following code?

    Promise.resolve(1)	
      .then(2)// then里传的不是函数,就相当于可以把这个then给删了
      .then(Promise.resolve(3))// then里传的不是函数,就相当于可以把这个then给删了
      .then(console.log)
    //等价于
    Promise.resolve(1)	
      .then(console.log)
    // 1
    
  8. What is the output of the following code?

    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');
    

    image-20230914211331453

    image-20230914210918609

  9. What is the output of the following code?

    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
    

Guess you like

Origin blog.csdn.net/qq_53461589/article/details/132918382