1 | 1、 const promise = new Promise((resolve, reject)=>{ |
运行结果是: 1,2,5,4
解释:promise的构造函数是同步执行,promise.then中的函数是异步执行。
1 | 2、 const promise = new Promise((resolve, reject) => { |
运行结果:then: success1
解释:构造函数中的 resolve 或 reject 只有第一次执行有效,多次调用没有任何作用。promise 状态一旦改变则不能再变。 promise 有 3 种状 态: pending、fulfilled 或 rejected。 状态改变只能是 pending->fulfilled 或者 pending-> rejected,状态一旦改变则不能再变。
1 | 3、const promise = new Promise((resolve, reject) => { |
运行结果: once success 1005 success 1007
解释:promise 的 .then 或者 .catch 可以被调用多次,但这里 Promise 构造函数只执行一次。或者说 promise 内部状态一经改变,并且有了一个值,那么后续每次调用 .then 或者 .catch 都会直接拿到该值。
1 | 4、console.log('start'); |
//输出结果: /* 立即输出 start 两秒输出 hello 再三秒 world */
5、上面我们在 then() 函数中返回的是一个新的promise,如果返回的不是一个新的promise会怎样呢?依然是上面的代码,稍作修改。
1 | console.log('start'); |
根据上面的运行结果来看,如果在一个then()中没有返回一个新的promise,则return 什么下一个then就接受什么,在上面的实例代码中return的是false,下一个 then中接受到的value就是false,如果then中没有return,则默认return的是 undefined.
6、then()中包含.then()的嵌套情况 then()的嵌套会先将内部的then()执行完毕再继续执行外部的then();在多个then嵌套时建议将其展开,将then()放在同一级,这样代码更清晰。
1 | console.log('start'); |
7、catch和then的连用 如果每一步都有可能出现错误,那么就可能出现catch后面接上then的情况。上代码
1 | new Promise((resolve,reject)=>{ |
8、Promise.all() 将多个Promise批量执行,所有的Promise都完毕之后返回一个新的Promise
1 | 1、接收一个数组作为参数 |
9、Promise.race() 和Promise.all()差不多,区别就是传入的数组中有一个Promise完成了则整个Promise完成了。
1 | let p1 = new Promise(resolve=>{ |
10、外部promise有多个then链式调用,第一个then里面执行另一个promise,也带多个then链式调用,他们的执行顺序会是怎样?
1 | new Promise((resolve, reject) => { |
1 | log: 外部promise |
解释
1,new promsie是同步代码,立即执行
2,外部promise第一个then需要等外部promise被resolve后才执行,外部promise立即被resolve,于是执行注册的then回调。此时外部第二then并未执行,因为他等待的是外部第一个then返回的promise
3,进入外部第一个then,回调里面是一个promise,执行内部promise时,同样两个then链式调用,内部第一个then执行后,内部promise算执行完,返回一个新的promise给内部第二then用
4,外部第一个then执行完且有返回值,进入外部第二then
5,之后执行内部第二then
看一个例子
1 | var p = new Promise((resolve, reject) => { |
p这个promise注册了两个then,注意跟链式调用then
的区别,这个就像发布订阅模式,有两个监听者,resolve时,这两个then同时执行,看完这个应该对上面理解有帮助
作者:小猪佩奇的王子
链接:https://www.jianshu.com/p/2c7c5285c7c5
来源:简书
https://segmentfault.com/a/1190000021717776
11.当一个promise进入settled状态时,它后面的then回调会被置入微任务队列。
settle的时机,决定了回调函数进入微队列的时间,决定了执行顺序。
https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
代码一:
1 | new Promise((resolve) => { |
从第三行开始
当Promise.resolve()接收一个thenable参数时,即刻产生了一个promise1,并返回这个promise1,这个promise1被 settle的时机是thenable.then的resolve被调用时。
当Promise.resolve({ then: … })执行完成,将thenable.then放入微任务队列,并返回一个promise1,然后执行了console.log(0)
console.log(0)执行完成后,(resolve) => { …. },这个代码块执行结束,调用栈清空,同时返回了一个promise0。
promise0立刻转为settle状态,致使() => console.log(3) 进入微任务队列
thenable.then在微任务队列弹出,执行console.log(1); resolve();
promise1 settle,导致() => console.log(2)进入微任务队列;
此时,微任务队列内还剩() => console.log(3)和() => console.log(2),根据入队顺序,依次被调用。
代码二:
1 | new Promise((resolve) => { |
依次执行
new Promise(…
resolve();
Promise.resolve().then(() => console.log(2)),此时Promise.resolve产生了一个promise1,并立即settle,导致console.log(2)进入微任务队列
new Promise(… 构造函数返回,生成了一个promise2。promise2即刻settle,导致() => console.log(4)进入微任务队列。
调用栈清空,开始依次执行微任务
作者:王老汉
链接:https://www.zhihu.com/question/388862445/answer/1170230704
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1 | function getJson(idx){ |
1 | const p1 = new Promise((resolve,reject)=>{ |
1 |
|