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行
Internal.prototype = redefineAll(PromiseConstructorPrototype, {// `Promise.prototype.then` method// https://tc39.es/ecma262/#sec-promise.prototype.thenthen: function then(onFulfilled, onRejected) {var state = getInternalPromiseState(this);// newPromiseCapability 把onFulfilled方法封装成一个自带promise属性的对象var reaction = newPromiseCapability(speciesConstructor(this, PromiseConstructor));reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;reaction.fail = typeof onRejected == 'function' && onRejected;reaction.domain = IS_NODE ? process.domain : undefined;state.parent = true;state.reactions.push(reaction);if (state.state != PENDING) notify(state, false);//如果不做任何操作,则在最后返回一个全新的promise,跟上次promise有不清楚的关系,因为传this了return reaction.promise;},// `Promise.prototype.catch` method// https://tc39.es/ecma262/#sec-promise.prototype.catch'catch': function (onRejected) {return this.then(undefined, onRejected);}});

p = new Promise((resolve,reject) => {resolve("success")}).then( str => {console.log(str)}).then(function(obj){console.log(typeof obj === 'undefined')//此处的this等于p.then返回的promise// p等于 p.then.then返回的pomiseconsole.log(this === p)})successtrue //obj === 'undefined' 因为虽然返回了Promise,但是没有参数falsePromise {<fulfilled>: undefined}[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: undefined
core-js
Internal.prototype = redefineAll(PromiseConstructorPrototype, {// `Promise.prototype.then` method// https://tc39.es/ecma262/#sec-promise.prototype.thenthen: function then(onFulfilled, onRejected) {var state = getInternalPromiseState(this);var reaction = newPromiseCapability(speciesConstructor(this, PromiseConstructor));reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;reaction.fail = typeof onRejected == 'function' && onRejected;reaction.domain = IS_NODE ? process.domain : undefined;state.parent = true;state.reactions.push(reaction);if (state.state != PENDING) notify(state, false);return reaction.promise;},// `Promise.prototype.catch` method// https://tc39.es/ecma262/#sec-promise.prototype.catch'catch': function (onRejected) {return this.then(undefined, onRejected);}//因为catch === this.then(undefined, onRejected);//所以catch下面能一直.then再来个例子:promise = new Promise(function(resolve, reject) {console.log('Promise');reject(1);}).then(undefined,res =>{console.log(res)//不return或者return undefined == return一个fulfilled状态的promise//(虽然是成功状态,但是里面没有参数) 可以无限.then()})// !!此时 下面的代码块就等于 .catch.then(undefined,res =>{console.log(res)})//因为'catch': function (onRejected) {return this.then(undefined, onRejected);}
案例
let p = new Promise((resolve,reject) => {resolve("success")}).then( str => {console.log(str)}).then(function(obj){console.log(1)return Promise// 如果上一行不renturn 东西,只要不报错,不返回错误状态的promise// 就等于返回一个新的没有传值的promse}).then(function(obj){console.log(2)}).then(function(obj){}).then(function(obj){})success12
let p = new Promise((resolve,reject) => {resolve("success")}).then( str => {console.log(str)}).then(function(obj){console.log(1)return new Promise(() => {//此处一直处于padding状态 所以也不会向下执行})//不传参数报错,Promise解析器未定义不是一个函数//Promise resolver undefined is not a function}).then(function(obj){console.log(2)})setTimeout(() => {console.log(p)}, 1000);success1Promise {<pending>} //一直处于pending状态的promise[[Prototype]]: Promise[[PromiseState]]: "pending"[[PromiseResult]]: undefined
let p = new Promise((resolve, reject) => {resolve("success")}).then(() => {console.log(1)}).then(() => {console.log(2)return Promise.reject("error")}).then(() => {console.log(3)}).catch(error => {console.log(error)}).// !!!上下同理!!!let p = new Promise((resolve, reject) => {resolve("success")}).then(() => {console.log(1)}).then(() => {console.log(2)throw "error"}).then(() => {console.log(3)}).catch(error => {console.log(error)})
tips
一、如果Promise 失败,则走reject,返回undefined,下一个then会走成功事件,这个值为undefined
axios.get("api").then(reponse =>{},error => {console.log("api请求失败")}).then(reponse =>{console.log("success",data)},error => {})此时打印的是:api请求失败success undefined
二、中断Promise
//返回一个初始化状态的promise即可中断promiseaxios.get("api").then(reponse =>{},error => {console.log("api请求失败")return new Promise(()=>{})})
总结
1. promise.then (只要不返回错误状态的promise 、抛出错误、返回一直pending的promise)他能一直then下去2. 可以用返回错误状态的promise 、抛出错误、返回一直pending的promise 打断promise的执行,例子见上面三个案例3. promise.catch 等于执行.then里面的onRejected方法,返回的是一个全新的promise详情可见core-js 他只是给reaction.fail赋值,返回的还是reaction.promise
promise里面的回调是立即执行的, 后面的then是在微任务队列里, 微任务产生的微任务还在本轮循环里
宏任务先执行, 大于微任务, 宏任务执行一个, 清空微任务队列, 再执行一个宏任务
整体js代码就是一个宏任务, 所以整体先执行, 遇见promise执行里面回调函数, then放在微任务里
然后继续执行同步代码
整体执行结束, 一个宏任务执行完了, 清空微任务
然后再执行宏任务
