Promise

https://www.wolai.com/pFYQMwgDhT1vkHPgrQgRmo?theme=light
源哥的promise代码⬆
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.promise.js

Promise底层代码,核心可看258行

  1. Internal.prototype = redefineAll(PromiseConstructorPrototype, {
  2. // `Promise.prototype.then` method
  3. // https://tc39.es/ecma262/#sec-promise.prototype.then
  4. then: function then(onFulfilled, onRejected) {
  5. var state = getInternalPromiseState(this);
  6. // newPromiseCapability 把onFulfilled方法封装成一个自带promise属性的对象
  7. var reaction = newPromiseCapability(speciesConstructor(this, PromiseConstructor));
  8. reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
  9. reaction.fail = typeof onRejected == 'function' && onRejected;
  10. reaction.domain = IS_NODE ? process.domain : undefined;
  11. state.parent = true;
  12. state.reactions.push(reaction);
  13. if (state.state != PENDING) notify(state, false);
  14. //如果不做任何操作,则在最后返回一个全新的promise,跟上次promise有不清楚的关系,因为传this了
  15. return reaction.promise;
  16. },
  17. // `Promise.prototype.catch` method
  18. // https://tc39.es/ecma262/#sec-promise.prototype.catch
  19. 'catch': function (onRejected) {
  20. return this.then(undefined, onRejected);
  21. }
  22. });

Promise - 图1

  1. p = new Promise((resolve,reject) => {
  2. resolve("success")
  3. }).then( str => {
  4. console.log(str)
  5. }).then(function(obj){
  6. console.log(typeof obj === 'undefined')
  7. //此处的this等于p.then返回的promise
  8. // p等于 p.then.then返回的pomise
  9. console.log(this === p)
  10. })
  11. success
  12. true //obj === 'undefined' 因为虽然返回了Promise,但是没有参数
  13. false
  14. Promise {<fulfilled>: undefined}
  15. [[Prototype]]: Promise
  16. [[PromiseState]]: "fulfilled"
  17. [[PromiseResult]]: undefined

core-js

  1. Internal.prototype = redefineAll(PromiseConstructorPrototype, {
  2. // `Promise.prototype.then` method
  3. // https://tc39.es/ecma262/#sec-promise.prototype.then
  4. then: function then(onFulfilled, onRejected) {
  5. var state = getInternalPromiseState(this);
  6. var reaction = newPromiseCapability(speciesConstructor(this, PromiseConstructor));
  7. reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
  8. reaction.fail = typeof onRejected == 'function' && onRejected;
  9. reaction.domain = IS_NODE ? process.domain : undefined;
  10. state.parent = true;
  11. state.reactions.push(reaction);
  12. if (state.state != PENDING) notify(state, false);
  13. return reaction.promise;
  14. },
  15. // `Promise.prototype.catch` method
  16. // https://tc39.es/ecma262/#sec-promise.prototype.catch
  17. 'catch': function (onRejected) {
  18. return this.then(undefined, onRejected);
  19. }
  20. //因为catch === this.then(undefined, onRejected);
  21. //所以catch下面能一直.then
  22. 再来个例子:
  23. promise = new Promise(function(resolve, reject) {
  24. console.log('Promise');
  25. reject(1);
  26. }).then(undefined,res =>{
  27. console.log(res)
  28. //不return或者return undefined == return一个fulfilled状态的promise
  29. //(虽然是成功状态,但是里面没有参数) 可以无限.then()
  30. })
  31. // !!此时 下面的代码块就等于 .catch
  32. .then(undefined,res =>{
  33. console.log(res)
  34. })
  35. //因为
  36. 'catch': function (onRejected) {
  37. return this.then(undefined, onRejected);
  38. }

案例

  1. let p = new Promise((resolve,reject) => {
  2. resolve("success")
  3. }).then( str => {
  4. console.log(str)
  5. }).then(function(obj){
  6. console.log(1)
  7. return Promise
  8. // 如果上一行不renturn 东西,只要不报错,不返回错误状态的promise
  9. // 就等于返回一个新的没有传值的promse
  10. }).then(function(obj){
  11. console.log(2)
  12. }).then(function(obj){
  13. }).then(function(obj){
  14. })
  15. success
  16. 1
  17. 2
  1. let p = new Promise((resolve,reject) => {
  2. resolve("success")
  3. }).then( str => {
  4. console.log(str)
  5. }).then(function(obj){
  6. console.log(1)
  7. return new Promise(() => {
  8. //此处一直处于padding状态 所以也不会向下执行
  9. })
  10. //不传参数报错,Promise解析器未定义不是一个函数
  11. //Promise resolver undefined is not a function
  12. }).then(function(obj){
  13. console.log(2)
  14. })
  15. setTimeout(() => {
  16. console.log(p)
  17. }, 1000);
  18. success
  19. 1
  20. Promise {<pending>} //一直处于pending状态的promise
  21. [[Prototype]]: Promise
  22. [[PromiseState]]: "pending"
  23. [[PromiseResult]]: undefined
  1. let p = new Promise((resolve, reject) => {
  2. resolve("success")
  3. }).then(() => {
  4. console.log(1)
  5. }).then(() => {
  6. console.log(2)
  7. return Promise.reject("error")
  8. }).then(() => {
  9. console.log(3)
  10. }).catch(error => {
  11. console.log(error)
  12. }).
  13. // !!!上下同理!!!
  14. let p = new Promise((resolve, reject) => {
  15. resolve("success")
  16. }).then(() => {
  17. console.log(1)
  18. }).then(() => {
  19. console.log(2)
  20. throw "error"
  21. }).then(() => {
  22. console.log(3)
  23. }).catch(error => {
  24. console.log(error)
  25. })

tips
一、如果Promise 失败,则走reject,返回undefined,下一个then会走成功事件,这个值为undefined

  1. axios.get("api").then(
  2. reponse =>{
  3. },
  4. error => {
  5. console.log("api请求失败")
  6. }
  7. )
  8. .then(
  9. reponse =>{
  10. console.log("success",data)
  11. },
  12. error => {
  13. }
  14. )
  15. 此时打印的是:
  16. api请求失败
  17. success undefined

二、中断Promise

  1. //返回一个初始化状态的promise即可中断promise
  2. axios.get("api").then(
  3. reponse =>{
  4. },
  5. error => {
  6. console.log("api请求失败")
  7. return new Promise(()=>{})
  8. }
  9. )

总结

  1. 1. promise.then (只要不返回错误状态的promise 、抛出错误、返回一直pendingpromise)
  2. 他能一直then下去
  3. 2. 可以用返回错误状态的promise 、抛出错误、返回一直pendingpromise 打断promise的执行,例子见上面三个案例
  4. 3. promise.catch 等于执行.then里面的onRejected方法,返回的是一个全新的promise
  5. 详情可见core-js 他只是给reaction.fail赋值,返回的还是reaction.promise

promise里面的回调是立即执行的, 后面的then是在微任务队列里, 微任务产生的微任务还在本轮循环里
宏任务先执行, 大于微任务, 宏任务执行一个, 清空微任务队列, 再执行一个宏任务
整体js代码就是一个宏任务, 所以整体先执行, 遇见promise执行里面回调函数, then放在微任务里
然后继续执行同步代码
整体执行结束, 一个宏任务执行完了, 清空微任务
然后再执行宏任务