• 令人疑惑的Promise相关问题


    令人疑惑的Promise相关问题

    问题1

    const promise = new Promise((resolve, reject) => {
      reject(Error('Error occurred'));
    });
    
    promise.catch(error => console.log(error.message));
    promise.catch(error => console.log(error.message));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出:

    Error occurred
    Error occurred
    
    • 1
    • 2

    解释:

    1. Promise 创建后立即被拒绝,并显示错误消息“发生错误”。
    2. Promise 附加了两个catch处理程序,当 Promise 被拒绝时,每个处理程序都会将错误消息记录到控制台。
    3. 由于 Promise 被拒绝,因此两个catch处理程序都将被执行,从而导致错误消息被记录两次。

    问题2

    console.log('start')
    
    const promise1 = new Promise((resolve, reject)=>{
    	console.log(1)
    })
    console.log('end')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出:

    start
    1
    end
    
    • 1
    • 2
    • 3

    解释:

    1. console.log(‘start’)语句首先执行,并将“start”记录到控制台。
    2. 构造Promise函数被调用,但它不包含任何异步操作或对 resolve 或 reject 的调用。因此,构造函数内的console.log(1)语句是同步执行的。
    3. 最后,console.log(‘end’)执行,将“end”记录到控制台。

    请记住,如果没有异步操作对Promise构造函数中 resolve 或 reject的进行调用,则 Promise 被视为立即解决,并且其行为是同步的。

    问题3

    function performTask() {
    	return new Promise(function(resolve, reject) {
    		reject()
    	})
    }
    
    let taskPromise = performTask();
    
    taskPromise.then(function() {
    		console.log('success 1')
    	}).then(function() {
    		console.log('success 2')
    	}).then(function() {
    		console.log('success 3')
    	}).catch(function() {
    		console.log('error 1')
    	}).then(function() {
    		console.log('success 4')
    	})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    输出:

    error 1
    success 4
    
    • 1
    • 2

    解释:

    1. performTask函数返回一个立即被拒绝的 Promise。
    2. 前三个.then()块被跳过,因为 Promise 被拒绝。
    3. .catch()块捕获拒绝并记录“错误 1”。
    4. 尽管出现错误,最后一个.then()块仍会执行,并将“Success 4”记录到控制台。这种行为是因为.catch()仅捕获前面的 Promise 链中的错误,而.then()无论之前的错误如何,都会执行后续块。

    问题4

    const promise = new Promise((resolve) => {
      resolve(1);
    });
    
    promise.then((value) => {
      console.log(value);
      return value + 1;
    }).then((value) => {
      console.log(value);
      throw new Error('Something went wrong');
    }).catch((error) => {
      console.error(error.message);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1
    2
    Error: Something went wrong
    
    • 1
    • 2
    • 3

    解释:

    1. 第一个 .then() 记录1到控制台并返回 value + 1,即2。
    2. 第二个 .then() 记录2到控制台,然后故意抛出错误。
    3. 错误被.catch()块捕获,并且错误消息 Something went wrong 被记录到控制台。

    此代码说明了异步操作与 Promise 的链接以及 .catch() 块如何捕获链中的错误。

    问题5

    const promise = new Promise(function(resolve, reject){
        setTimeout(function() {
            resolve('Resolved!');
        }, 1000);
    });
    
    promise.then(function(value) {
        console.log(value)
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    输出:

    # 1秒后打印
    Resolved!
    
    • 1
    • 2

    解释:

    1. setTimeout引入了延迟,使得 Promise 在 1000 毫秒后解析。
    2. 当 Promise 被解析时,.then() 块被执行,并且将 Resolved! 记录到控制台。

    问题6

    const promise = new Promise(function(resolve, reject){
        setTimeout(() => resolve(1), 1000);
    });
    
    promise.then(function(result){
    		console.log(result);
    		return result * 2;
    	}).then(function(result){
    		console.log(result);
    		return result * 2;
    	}).then(function(result){
    		console.log(result);
    		return result * 2;
    	});
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    输出:

    1
    2
    4
    
    • 1
    • 2
    • 3

    解释:

    1. 在用值解析 Promise 之前引入 setTimeout 并设置了 1000 毫秒的延迟。
    2. 每个 .then() 块对先前的结果执行操作并记录更新的值。
    3. 处理程序的链接 .then() 允许顺序处理异步结果。

    问题7

    console.log('Start');
    setTimeout(() => {
     console.log('Timeout');
    }, 0);
    Promise.resolve().then(() => {
     console.log('Promise resolved');
    });
    console.log('End');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    输出:

    Start
    End
    Promise resolved
    Timeout
    
    • 1
    • 2
    • 3
    • 4

    解释:

    1. console.log(‘Start’);:同步操作,将“Start”记录到控制台。
    2. setTimeout(() => { console.log(‘Timeout’); }, 0);:使用 setTimeout 异步操作。即使超时设置为0毫秒,当前同步代码执行完毕后仍然会执行。将 Timeout 记录到控制台。
    3. Promise.resolve().then(() => { console.log(‘Promise resolved’); });:使用已解析的 Promise 进行异步操作。这将在当前同步代码之后的事件循环的下一个周期中执行。将 Promise resolved 记录到控制台。
    4. console.log(‘End’);:同步操作,将 End 记录到控制台。

    问题8

    let firstTask = new Promise(function(resolve, reject) {
      setTimeout(resolve, 500, 'Task One');
    });
    
    let secondTask;
    
    let thirdTask = new Promise(function(resolve, reject) {
      setTimeout(resolve, 1200, 'Task Three');
    });
    
    let fourthTask = new Promise(function(resolve, reject) {
      setTimeout(reject, 300, 'Task Four');
    });
    
    let fifthTask = new Promise(function(resolve, reject) {
      setTimeout(resolve, 1000, 'Task Two');
    });
    
    let combinedPromise = Promise.all([firstTask, secondTask, thirdTask, fourthTask, fifthTask]);
    
    combinedPromise
      .then(function(data) {
        data.forEach(function(value) {
          console.log('Result:', value);
        });
      })
      .catch(function(error) {
        console.error('Error:', error);
      });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    输出:

    Error: Task Four
    
    • 1

    解释:

    1. 500 毫秒后解析firstTask值为’Task One’。
    2. secondTask未初始化,因此它被视为具有 undefined 值的已解决的 Promise。
    3. 1200 毫秒后解析 thirdTask 值为’Task Three’。
    4. 设置 fourthTask 为在 300 毫秒后拒绝,值为’Task Four’。
    5. 1000 毫秒后解析 fifthTask 值为’Task Two’。

    问题9

    const promise1 = new Promise(resolve => setTimeout(resolve, 100, 'One'));
    const promise2 = new Promise(resolve => setTimeout(resolve, 200, 'Two'));
    
    Promise.race([promise1, promise2])
      .then(value => console.log(value))
      .catch(error => console.error(error));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出:

    One
    
    • 1

    解释:

    1. 创建两个 Promise(promise1和promise2)并使用 setTimeout 来模拟异步操作。
    2. 用于Promise.race解决或拒绝第一个已解决的承诺(解决或拒绝)。
    3. 在这种情况下,promise1首先返回结果(100 毫秒后),因此 .then 块被执行,并将“One”记录到控制台。
    4. 由于没有拒绝,因此不会触发 .catch 块。

    问题10

    const promise1 = Promise.resolve(1);
    const promise2 = new Promise(resolve => setTimeout(resolve, 200));
    const promise3 = new Promise((resolve, reject) => setTimeout(reject, 100, 'Error'));
    
    Promise.all([promise1, promise2, promise3])
      .then(values => console.log(values))
      .catch(error => console.error(error));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    输出:

    Error
    
    • 1

    解释:

    1. promise1立即返回结果1。

    2. promise2 在200 毫秒超时后解决。

    3. promise3 在 100 毫秒超时后被拒绝,并给出原因 ‘Error’。

    Promise.all()方法采用 Promise 数组作为参数,并返回一个新的 Promise,当可迭代参数中的所有 Promise 都已实现时,Promise 将通过已实现值的数组来实现。如果数组中的任何一个 Promise 被拒绝,则最终的 Promise 也会被拒绝,并给出第一个被拒绝的 Promise 的原因。

    由于 Promise ( promise3) 之一被拒绝,因此 Promise.all() 被拒绝,并且 catch 块被执行。因此,代码的输出将是 Error。

    问题11

    Promise.resolve(1)
      .then(value => {
        console.log(value);
        return Promise.resolve(2);
      })
      .then(value => console.log(value));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出:

    1
    2
    
    • 1
    • 2

    解释:

    1. Promise.resolve(1)创建一个立即处理的 Promise 1。

    2. 第一个 .then() 块将解析值记录 1 到控制台并返回一个新的 Promise ( Promise.resolve(2))。

    3. 第二个 .then() 块将解析值记录2到控制台。

    结论

    总之,掌握 Promise 对于熟练的异步编程至关重要。了解 Promise 链、执行顺序以及诸如 Promise.all 和 Promise.race 之类的细微差别至关重要。通过有效的 catch 错误处理确保代码的健壮性。async/await 的出现简化了异步代码,提供了更加同步的格式。

    未处理的Promise reject可能会导致警告或错误,这强调了正确的错误管理的重要性。可以精确地编排异步操作,使开发人员能够创建高效且响应迅速的应用程序。

  • 相关阅读:
    java计算机毕业设计响应式交友网站源码+系统+mysql数据库+lw文档+部署
    HashMap详解
    银河麒麟安装arm架构mysql8
    UniApp 中 nvue 盒模型入门
    DeepMind 发了篇论文,把我看笑了
    各位程序员们,睡眠不足产生的后果超出你想象!
    2022-08-01 C++并发编程(四)
    STM32(15)USART编程
    每天一个数据分析题(三百九十九)- 逻辑回归
    在Vue3中使用Element-Plus分页(Pagination )组件
  • 原文地址:https://blog.csdn.net/qq_42880714/article/details/134701712