【Promise】代码输出面试题

10 篇文章 1 订阅

【Promise】代码输出面试题

promise相关

1.1

const promise = new Promise((resolve, reject) => {
  console.log(1);
  setTimeout(() => {
    console.log("timerStart");
    resolve("success");
    console.log("timerEnd");
  }, 0);
  console.log(2);
});
promise.then((res) => {
  console.log(res);
});
console.log(4);

执行结果为:

1
2
4
"timerStart"
"timerEnd"
"success"

分析:

  • 先遇到promise,输出1,碰到了定时器,将setTimeout放到下一个宏任务队列中,输出2

  • 跳出promise,遇到promise.then,但其状态还是为pending,这里认为先不执行

  • 输出4

  • 一轮循环过后,进入第二次宏任务,执行setTimeout,输出timeStart,然后遇到了resolve,改变promise的状态,此时将 promise.then 推入微任务队列

  • 继续输出timerEnd

  • 宏任务执行完毕,执行微任务,执行promise.then


1.2

const promise = new Promise((resolve, reject) => {
  reject("error");
  resolve("success2");
});
promise
    .then(res => {
    console.log("then1: ", res);
  }).then(res => {
    console.log("then2: ", res);
  }).catch(err => {
    console.log("catch: ", err);
  }).then(res => {
    console.log("then3: ", res);
  })

结果:

"catch: " "error"
"then3: " undefined

分析:

  • catch不管被连接到哪里,都能捕获上层未捕捉过的错误。
  • 下面的then3也会被执行,因为catch的返回值是undefined

1.3

Promise.resolve().then(() => {
  return new Error('error!!!')
}).then(res => {
  console.log("then: ", res)
}).catch(err => {
  console.log("catch: ", err)
})

结果:

"then: " "Error: error!!!"

分析:

return 一个非 promise 的值都会被包裹成 promise 对象,因此这里的return new Error('error!!!')也被包裹成了return Promise.resolve(new Error('error!!!'))

这里要注意区 return error 和 throw new error

  • 对于 return error,会将它包裹成一个promise返回,是成功的状态
  • 而 throw new error,会返回失败
// 举例
Promise.resolve().then(() => {
  throw new Error('error!!!')
}).then(res => {
  console.log("then: ",res)
}).catch(err => {
  console.log("catch: ",err) //catch:  Error: error!!!
})

1.4

Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .then(console.log)

结果:

1

分析:

.then 或者 .catch 的参数期望是函数,传入非函数则会发生值透传。

第一个then和第二个then中传入的都不是函数,一个是数字类型,一个是对象类型,因此发生了透传,将resolve(1) 的值直接传到最后一个then里。

如果传入的不是函数,那么最开始的值并不会在它们中改变,而是会继续向下传递。


1.5 --> finally

  • .finally()方法不管Promise对象最后的状态如何都会执行

  • .finally()方法的回调函数不接受任何的参数,也就是说你在.finally()函数中是没法知道Promise最终的状态是resolved还是rejected

  • 它最终返回的默认会是一个上一次的Promise对象值,不过如果抛出的是一个异常则返回异常的Promise对象。

  • 在finally中,return 值 不起作用,参照上面的第三条

  • finally 如果抛出的是一个异常则返回异常的Promise对象

    Promise.resolve('1')
      .finally(() => {
        console.log('finally1')
        throw new Error('我是finally中抛出的异常')
      })
      .then(res => {
        console.log('finally后面的then函数', res)
      })
      .catch(err => {
        console.log('捕获错误', err)
      })
    

    执行结果为:

    'finally1'
    '捕获错误' Error: 我是finally中抛出的异常
    

    但是如果改为return new Error('我是finally中抛出的异常'),打印出来的就是'finally后面的then函数 1'

Promise.resolve('1')
  .then(res => {
    console.log(res)
  })
  .finally(() => {
    console.log('finally')
  })
Promise.resolve('2')
  .finally(() => {
    console.log('finally2')
  	return '我是finally2返回的值
  })
  .then(res => {
    console.log('finally2后面的then函数', res)
  })

结果:

'1'
'finally2'
'finally'
'finally2后面的then函数' '2'

分析:

要注意:finally2 会在 finally 之前输出

  • 首先将第一个promise的then加入微任务队列,这里要注意,代码并不会接着往链式调用的下面走,也就是不会先将.finally加入微任务列表,那是因为.then本身就是一个微任务,它链式后面的内容必须得等当前这个微任务执行完才会执行,因此这里我们先不管.finally()
  • 再向下遇到了第二个promise,将它的finally加入微任务队列,并且它后面的then不会加入微任务队列,和第一个promise相同。
  • 此时,本轮的宏任务全部执行完毕,执行微任务队列,输出1,然后遇到了第一个promise的finally,将它加入微任务队列,再取出微任务队列中的第二个任务(即第二个promise的finally),输出finally2,然后向下遇到了then,并将第二个promise的then加入微任务队列。
  • 此时,本轮已全部执行完,开启新一轮的任务,执行微任务队列,分别输出finally'finally2后面的then函数' '2'

1.6

function promise1 () {
  let p = new Promise((resolve) => {
    console.log('promise1');
    resolve('1')
  })
  return p;
}
function promise2 () {
  return new Promise((resolve, reject) => {
    reject('error')
  })
}
promise1()
  .then(res => console.log(res))
  .catch(err => console.log(err))
  .finally(() => console.log('finally1'))

promise2()
  .then(res => console.log(res))
  .catch(err => console.log(err))
  .finally(() => console.log('finally2'))

结果:

'promise1'
'1'
'error'
'finally1'
'finally2'

分析:

  • 首先定义了两个函数promise1promise2,先不管接着往下看。
  • promise1函数先被调用了,然后执行里面new Promise的同步代码打印出promise1
  • 之后遇到了resolve(1),将p的状态改为了resolved并将结果保存下来。
  • 此时promise1内的函数内容已经执行完了,跳出该函数
  • 碰到了promise1().then(),由于promise1的状态已经发生了改变且为resolved因此将promise1().then()这条微任务加入本轮的微任务列表(这是第一个微任务)
  • 这时候要注意了,代码并不会接着往链式调用的下面走,也就是不会先将.finally加入微任务列表,那是因为.then本身就是一个微任务,它链式后面的内容必须得等当前这个微任务执行完才会执行,因此这里我们先不管.finally()
  • 再往下走碰到了promise2()函数,其中返回的new Promise中并没有同步代码需要执行,所以执行reject('error')的时候将promise2函数中的Promise的状态变为了rejected
  • 跳出promise2函数,遇到了promise2().catch(),将其加入当前的微任务队列(这是第二个微任务),且链式调用后面的内容得等该任务执行完后才执行,和.then()一样。
  • OK, 本轮的宏任务全部执行完了,来看看微任务列表,存在promise1().then(),执行它,打印出1,然后遇到了.finally()这个微任务将它加入微任务列表(这是第三个微任务)等待执行
  • 再执行promise2().catch()打印出error,执行完后将finally2加入微任务加入微任务列表(这是第四个微任务)
  • OK, 本轮又全部执行完了,但是微任务列表还有两个新的微任务没有执行完,因此依次执行finally1finally2

1.7

const first = () => (new Promise((resolve, reject) => {
    console.log(3);
    let p = new Promise((resolve, reject) => {
        console.log(7);
        setTimeout(() => {
            console.log(5);
            resolve(6);
            console.log(p)
        }, 0)
        resolve(1);
    });
    resolve(2);
    p.then((arg) => {
        console.log(arg);
    });
}));
first().then((arg) => {
    console.log(arg);
});
console.log(4);

结果:

3
7
4
1
2
5
Promise{<resolved>: 1}

分析:

  • 首先执行first函数,它的返回值是一个promise。先输出3,接着输出7,遇到一个定时器,将它放入宏任务队列。接着遇到了resolve(1),这里就把p的状态改为了resolved,且返回值为1,不过这里也先不执行
  • 跳出p,碰到了resolve(2),这里的resolve(2),表示的是把first函数返回的那个Promise的状态改了。
  • 然后碰到了p.then,将它加入本次循环的微任务列表,等待执行。
  • 跳出first函数,遇到了first().then(),将它加入本次循环的微任务列表(p.then的后面执行)。这里要将first().then()加入队列的原因是:first函数返回值是一个promise,并且resolve(2),把first函数返回的那个Promise的状态改了。
  • 然后执行同步代码4
  • 本轮的同步代码全部执行完毕,查找微任务列表,发现p.thenfirst().then(),依次执行,打印出1和2
  • 然后执行宏任务中的定时器,执行同步代码5,然后又遇到了一个resolve(6),它是放在p里的,但是p的状态在之前已经发生过改变了,因此这里就不会再改变,也就是说resolve(6)相当于没任何用处,因此打印出来的pPromise{<resolved>: 1}。注意:promise的状态只会改变一次。

1.8

const p1 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('resolve3');
    console.log('timer1')
  }, 0)
  resolve('resovle1');
  resolve('resolve2');
}).then(res => {
  console.log(res)
  setTimeout(() => {
    console.log(p1)
  }, 1000)
}).finally(res => {
  console.log('finally', res)
})

结果:

'resolve1'
'finally' undefined
'timer1'
Promise{<resolved>: undefined}

分析:

  • Promise的状态一旦改变就无法改变

  • finally不管Promise的状态是resolved还是rejected都会执行,且它的回调函数是接收不到Promise的结果的,所以finally()中的res是一个迷惑项。

  • 最后一个定时器打印出的p1其实是.finally的返回值,我们知道.finally的返回值如果在没有抛出错误的情况下默认会是上一个Promise的返回值, 而这道题中.finally上一个Promise.then(),但是这个.then()并没有返回值,所以p1打印出来的Promise的值会是undefined,如果你在定时器的下面加上一个return 1,则值就会变成1


关于promise.then.then

2.1

Promise.resolve()
  .then(() => { 
    Promise.resolve().then(() => {
      console.log(1);
    }).then(() => {
      console.log(2);
    })
  })
  .then(() => { 
    console.log(3)
  })

结果:

1 3 2

分析:

先将外层第一个 then 压入微任务列表,等待这个 then 执行完返回一个 promise 之后再将外层第二个 then 压入微任务队列,第一个then里面的逻辑同样如此。

对每一个then标号,便于表述

Promise.resolve()
  .then(() => {  //1.0
    Promise.resolve().then(() => { //1.1
      console.log(1);
    }).then(() => { //1.2
      console.log(2);
    })
  })
  .then(() => { //2.0
    console.log(3)
  })
  • 首先将then1.0放入微任务队列,本轮宏任务执行完毕,取出then1.0,执行发现里面是then1.1,所以将then1.1加入微任务队列
  • 在第二轮,取出then1.1,执行输出1,此时then1.0就有了返回值,返回值是then1.1 里return的undefined。根据优先级,优先将then2.0加入队列,然后将then1.2加入队列。
  • 在新的一轮,取出then2.0,输出3,再取出then1.2,输出2

2.2

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

结果:

1 2 3 4 5

分析:

Promise.resolve()
  .then(() => { //1.0
    Promise.resolve().then(() => { //1.1
      console.log(1);
    }).then(() => { //1.2
      console.log(2);
    })
  })
  .then(() => { //2.0
    Promise.resolve().then(() => { //2.1
      console.log(3);
    }).then(() => { //2.2
      console.log(4);
    }).then(() => { //2.3
      console.log(5)
    })
  })
  • 先将then1.0加入微任务队列,本轮宏任务执行完毕,取出then1.0,执行发现是then1.1,放入微任务队列
  • 下一轮,取出then1.1执行,输出1,此时then1.0已经有了返回值,返回值是then1.1的return undefined。那么根据优先级,先将then2.0加入队列,然后加入then1.2
  • 取出then2.0,执行发现是一个then2.1,放入队列,取出then1.2,执行输出2
  • 下一轮,取出then2.1,输出3,然后将then2.2加入队列,下一轮取出输出4,再将then2.3加入队列…

2.3

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

结果:

1 3 2 6 4 5

分析:

Promise.resolve()
  .then(() => { //1.0
    Promise.resolve().then(() => { //1.1
      console.log(1);
    }).then(() => { //1.2
      console.log(2);
    }).then(() => { //1.3
      console.log(6)
    })
  })
  .then(() => { //2.0
    console.log(3)
  })
  .then(() => { //3.0
    Promise.resolve().then(() => { //3.1
      console.log(4);
    }).then(() => { //3.2
      console.log(5);
    })
  })
  • then1.0加入队列,下一轮取出,then1.1加入队列,下一轮取出,执行then1.1,输出1,此时then1.0已经有了返回值,根据优先级,先将then2.0加入队列,然后将then1.2加入队列。
  • 新的一轮,取出then2.0,输出3,此时then2.0已经有了返回值,返回值为return的undefined,那么将then3.0加入队列。然后取出then1.2,输出2,然后将then1.3加入队列。
  • 新的一轮,取出then3.0,执行发现是then3.1,将then3.1加入队列。取出then1.3,输出6
  • 新的一轮,取出then3.1,输出4,再将then3.2加入队列,最后输出5

2.4

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

结果:

1 2 4 3 5

分析:

Promise.resolve()
  .then(() => { //1.0
    Promise.resolve().then(() => { //1.1
      console.log(1);
    }).then(() => { //1.2
      console.log(2);
    })
  })
  .then(() => { //2.0
    Promise.resolve().then(() => { //2.1
      console.log(4);
    }).then(() => { //2.2
      console.log(5);
    })
  })
  .then(() => { //3.0
    console.log(3)
  })
  • then1.0入队列,然后取出执行发现是then1.1,then1.1入队列,取出执行输出1。此时then1.0有了返回值,将then2.0加入队列,再将then1.2加入队列。
  • 新的一轮,取出then2.0,执行发现是then2.1,加入队列,再取出then1.2,输出2
  • 新的一轮,取出then2.1,输出4,此时then2.0有了返回值,将then3.0加入队列,再将then2.2加入队列
  • 新的一轮,取出then3.0,输出3,然后取出then2.2,输出5

2.5

new Promise((resolve, reject) => {
  console.log(1)
  resolve()
})
  .then(() => {  
    console.log(2)
    new Promise((resolve, reject) => {
      console.log(3)
      resolve()
    }).then(() => { 
      console.log(4)
    }).then(() => {  
      console.log(5)
    })
  })
  .then(() => {  
    console.log(6)
  })

new Promise((resolve, reject) => {
  console.log(7)
  resolve()
}).then(() => { 
  console.log(8)
})

结果:

1 7 2 3 8 4 6 5

分析:

new Promise((resolve, reject) => {
  console.log(1)
  resolve()
})
  .then(() => {  //1.0
    console.log(2)
    new Promise((resolve, reject) => {
      console.log(3)
      resolve()
    }).then(() => {  //1.1
      console.log(4)
    }).then(() => { //1.2
      console.log(5)
    })
  })
  .then(() => {  //2.0
    console.log(6)
  })

new Promise((resolve, reject) => {
  console.log(7)
  resolve()
}).then(() => {  //3.0
  console.log(8)
})
  • 首先输出同步代码,输出1,看见solve,将then1.0加入队列。then2.0暂时先不管,只有当then1.0有了返回的promise时,then2.0才会入队列。
  • 继续向下执行,输出7,看见resolve,将then3.0加入队列。
  • 新的一轮,取出then1.0,输出2,然后输出3,看见resolve,将then1.1加入队列。然后取出then3.0,输出8
  • 新的一轮,取出then1.1,输出4,此时then1.0已经有了返回值,根据优先级,先将then2.0加入队列,然后将then1.2加入队列。
  • 新的一轮,取出then2.0,输出6,然后取出then1.2,输出5

2.6

从 2.1~2.5,他们的返回值都出现在then返回的值,这个题是自己手动返回一个promise。

then方法会自动返回一个新的Promise,相当于return new Promise,

但是如果你手动写了return Promise,那return的就是你手动写的这个Promise

new Promise((resolve, reject) => {
  console.log(1)
  resolve()
})
  .then(() => {
    console.log(2)
    // 这里多了个return,是自己返回的promise
    return new Promise((resolve, reject) => {
      console.log(3)
      resolve()
    }).then(() => {
      console.log(4)
    }).then(() => { // 相当于return了这个then的执行返回Promise
      console.log(5)
    })
  })
  .then(() => {
    console.log(6) 
  })

结果:

1 2 3 4 5 6

分析:

new Promise((resolve, reject) => {
  console.log(1)
  resolve()
})
  .then(() => { //1.0
    console.log(2)

    return new Promise((resolve, reject) => {
      console.log(3)
      resolve()
    }).then(() => { //1.1
      console.log(4)
    }).then(() => {  //1.2
      console.log(5)
    })
  })
  .then(() => { //2.0
    console.log(6) 
  })
  • 首先输出1,遇到了resolve,将then1.0加入队列,then2.0先不管
  • 取出then1.0,输出2,因为这个then1.0的返回值是自己手动返回的一个promise,所以只有当这个promise执行结束的返回值时,才会将then2.0加入队列。
  • 然后输出3,然后遇到了resolve,将then1.1加入队列。下一轮取出输出4,然后将then1.2加入队列,新的一轮,输出5
  • 此时then1.0的最终返回值为undefined,然后将then2.0加入队列,下一轮取出,并输出6

为了验证then2.0拿到的是我们自己手动返回的promise的最终的值,我们对代码进行改动来验证。

new Promise((resolve, reject) => {
  console.log(1)
  resolve()
})
  .then(() => {
    console.log(2)
    // 多了个return
    return new Promise((resolve, reject) => {
      console.log(3)
      resolve()
    }).then(() => {
      console.log(4)
    }).then(() => { // 相当于return了这个then的执行返回Promise
      console.log(5)
      return "then1.0" //我们自己返回的值是"then1.0"
    })
  })
  .then((res) => {
    console.log(res) //将从then1.0拿到的值进行输出
  })

结果:

1
2
3
4
5
then1.0

async,await相关

关于 async 和 await 的事件循环的规则,
请点击这里👉【JavaScript】EventLoop

可以理解为「紧跟着await后面的语句相当于放到了new Promise中,下一行及之后的语句相当于放在Promise.then中」。

3.1

async function async1 () {
  console.log('async1 start');
  await new Promise(resolve => {
    console.log('promise1')
  })
  console.log('async1 success');
  return 'async1 end'
}
console.log('script start')
async1().then(res => console.log(res))
console.log('script end')

结果:

'script start'
'async1 start'
'promise1'
'script end'

分析:

  • 是先输出script start,因为async1函数虽然是同步执行,但是要先调用async1函数,才能执行,这里开始的时候并没有调用
  • 在输出完promise1后,这个promise并没有返回值,也就是它的状态始终是pending状态,因此相当于一直在awaitawaitawait却始终没有响应…
  • 所以await下面的代码不会进入微任务队列,.then也不会

3.2

这里给await 的promise加上resolve,使它的状态发生变化

async function async1 () {
  console.log('async1 start');
  await new Promise(resolve => {
    console.log('promise1')
    resolve('promise1 resolve')
  }).then(res => console.log(res))
  console.log('async1 success');
  return 'async1 end'
}
console.log('srcipt start')
async1().then(res => console.log(res))
console.log('srcipt end')

结果:

'script start'
'async1 start'
'promise1'
'script end'
'promise1 resolve'
'async1 success'
'async1 end'

分析:

  • 现在Promise有了返回值了,因此await后面的内容将会被执行

  • 那么await后面的promise的.then会被加入微任务队列,然后await下面的代码会当做promise.then加入队列。

  • async1().then(res => console.log(res)),的.then也会被加入队列


3.3 --> try catch

await后面跟着的是一个状态为rejectedpromise

如果在async函数中抛出了错误,则终止错误结果,不会继续向下执行。

如果想要使得错误的地方不影响async函数后续的执行的话,可以使用try catch

async function async1 () {
  await async2();
  console.log('async1');
  return 'async1 success'
}
async function async2 () {
  return new Promise((resolve, reject) => {
    console.log('async2')
    reject('error')
  })
}
async1().then(res => console.log(res))

结果:

'async2'
Uncaught (in promise) error
async function async1 () {
  try {
    await Promise.reject('error!!!')
  } catch(e) {
    console.log(e)
  }
  console.log('async1');
  return Promise.resolve('async1 success')
}
async1().then(res => console.log(res))
console.log('script start')

结果:

'script start'
'error!!!'
'async1'
'async1 success'

分析:

  • 首先执行async1函数,在try中等到一个reject,因为有await,那么await下面的代码被看成promise.then,放入微任务队列。
  • 向下执行,.then放入微任务队列,继续向下,输出script start
  • 本轮循环结束,在下一轮循环中,依次取出两个微任务进行执行

3.4

let p = new Promise((resolve, reject) => {
  setTimeout(() => {
      resolve(10)  
  }, 1000)
}).then(() => {
     throw Error("1123")
}).catch((err) => {
  console.log(err);
})
.then(() => {
  console.log('异常捕获后可以继续.then');
})

/**
 *  Error: 1123
    at e:\note\前端\代码\vue\promise\6.js:6:12
    异常捕获后可以继续.then
 */

3.5

const async1 = async () => {
  console.log('async1');
  setTimeout(() => {
    console.log('timer1')
  }, 2000)
  await new Promise(resolve => {
    console.log('promise1')
  })
  console.log('async1 end')
  return 'async1 success'
} 
console.log('script start');
async1().then(res => console.log(res));
console.log('script end');
Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .catch(4)
  .then(res => console.log(res))
setTimeout(() => {
  console.log('timer2')
}, 1000)

结果:

'script start'
'async1'
'promise1'
'script end'
1
'timer2'
'timer1'

分析:

  • async函数中awaitnew Promise要是没有返回值的话则不执行后面的内容
  • .then函数中的参数期待的是函数,如果不是函数的话会发生透传
  • 注意定时器的延迟时间

3.6

let a;

const b = new Promise((resolve, reject) => {
  console.log('promise1');
  resolve();
}).then(() => { //then1
  console.log('promise2');
}).then(() => { //then2
  console.log('promise3');
}).then(() => { //then3
  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');

结果:

promise1
undefined
end
promise2
promise3
promise4
Promise { <pending> }
after1

分析:

  • 首先执行promise中的同步代码,输出promise1,然后遇到了resolve,将then1加入微任务队列,后面的then2和then3不用管。

  • 继续向下执行,遇到console.log(a) ,这里是在promise里的代码,所以会同步输出,此时主代码还未执行完毕,所以a还未赋值,那么a的值为undefined。输出undefined。然后向下执行,同步执行await b

  • 在b中,then是异步代码,先跳过,继续向下执行。

  • 输出同步代码end,此时主代码执行完毕,那么a也被赋值了,因为a的值是一个promise,而这个promise并没有指定状态,所以a的值为pending

  • 接下来执行异步代码,取出then1,输出promise2,then1的返回值为undefined,将then2加入队列,下一轮取出并执行,输出promise3,然后将then3加入队列,下一轮输出promise4

  • 此时await b已执行完,将await b下面的代码作为微任务加入队列。

  • 下一轮取出,执行输出a,在前面的代码中,并没有给再次a赋值,所以此时a的值仍为pending,所以输出Promise { <pending> }

  • 然后继续输出after1。接下来执行await a,因为a一直为pending状态,所以相当于一直在awaitawaitawait却始终没有响应…那么后序代码也不会执行。


关于 Promise.resolve

  • Promise.resolve的状态由()里面决定,如果里面是reject,那么即使是Promise.resolve,也会返回reject
  • reject不管传入的是什么值,都会按reject处理
const promise = Promise.resolve(new Promise((resolve,reject) => {
  reject("111");
}))

promise.then(res => {
  console.log("res: ",res)
},err => {
  console.log("err: ",err)//err:  111
})
const p = Promise.reject("222")
//如果是一个常量,返回值是一个reject

p.then(res => {
  console.log("res: ",res)
},err => {
  console.log("err: ",err)//err: 222
})

//# reject不管传入的是什么值,都会按reject处理
const p1 = Promise.reject(new Promise((resolve,reject) => {
   resolve("333")
}))

p1.then(res => {
  console.log("res: ",res)
},err => {
  console.log("err: ",err)//err:  Promise { '333' }
}).catch(err => {
  console.log("catch err:",err)
})

4.1

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('400');
  }, 3000)
});

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(p1);  
  }, 1000)
})


p2.then(res => console.log(res))
  .catch(err => console.log('error:'+err)); //error:400

//这里如果想看p1,p2的状态,不能立即输出,得用setTimeout
setTimeout(() => {
  console.log("p1: ",p1)//Promise { <rejected> '400' }
  console.log("p2: ",p2)//Promise { <rejected> '400' }
}, 5000);

分析:
当 promise 状态存在依赖时,它的状态与自身无关了,由依赖来决定,对于上述代码,就是 p2 的状态由依赖 p1 来决定,而p1是 reject,所以p2也是 reject

这里很像 Promise.resolve


总结:

1.对于promise.then,将它推入微任务队列的时机为promise状态发生变化时(即出现resolve或reject或抛出异常时),而不是遇到了就把它推入队列。eg: 1.1

2.要注意区分 return new Error 和 throw new Error。eg: 1.3

3.对于一个promise.then.then,它并不会一次将这两个then都加入微任务队列,而是只会加入第一个then,跳过第二个,等到第二轮循环时,取出第一个then并执行后,才会加入第二个then。eg: 1.5

4.promise并没有返回值,也就是它的状态始终是pending状态,因此相当于一直在awaitawaitawait却始终没有响应… eg: 2.1

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序媛小y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值