Promise总结

4 篇文章 0 订阅

引入

众所周知,Javascript是一种单线程的语言,所有的代码必须按照所谓的“自上而下”的顺序来执行。本特性带来的问题就是,一些将来的、未知的操作,必须异步实现(关于异步,我会在另一篇文章里进行讨论)。本文将讨论一个比较常见的异步解决方案——Promise。

Promise基本概念的介绍

Promise是什么?

对于Promise,我们需要分为两个部分进行理解,一个是Promise构造函数,一个是Promise构造函数创建出来的实例

  1. Promise是一个构造函数,既然是构造函数,那我们就可以通过new Promise()得到一个Promise的实例
var promise = new Promise(function(){})
  1. 一个 Promise实例就是一个对象,同时,它可以代表一个异步操作的结果

为什么要用Promise:回调地狱——读取多个文件

//需求:先读取文件1,再读取文件2,最后再读取文件3
//回调地狱
//使用ES6 中的Promise,来解决回调地狱的问题;
//问:Promise 的本质是干什么:就是单纯为了解决回调地狱问题,并不能帮我们减少代码量
getFileByPath(path.join(__dirname,'./files/1.txt'),function(data){
	console.log(data)
	getFileByPath(path.join(__dirname,'./files/2.txt'),function(data){
		console.log(data)
		getFileByPath(path.join(__dirname,'./files/3.txt'),function(data){
			console.log(data)
		})
	})
})

如何使用Promise构造函数

1. 使用构造函数创建实例。

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve(成功之后的回调函数)和reject(失败之后的回调函数),promise构造函数每当创建一个实例的时候,就会立刻执行这个传入的函数中除了异步操作以外的内容,并且记录下当前时刻的状态

const promise = new Promise(function(resolve, reject){
    console.log('ok');
    //下面的是回调函数,resolve在then传入具体的回调函数时才会执行。
    resolve('ok');
});//ok

2. then方法定制成功失败回调函数

then方法存在于在Promise构造函数的Prototype属性上,也就是说,只要是Promise构造函数创建的实例,都可以访问到then()方法

promise.then(value=>console.log('-data----'+value),err=>console.log('-err-----'+err));//-data----ok

如上,then方法中可以传入两个参数,分别为resolve函数(成功的回调函数)和reject函数(失败的回调函数)。

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去

reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

这个异步操作的结果,只能有两种状态

  1. 异步执行成功,需要在内部调用成功的回调函数resolve把结果返回给调用者
  2. 异步执行失败,需要在内部调用失败的回调函数reject把结果返回给调用者
  3. 一旦函数执行的状态确定了,就无法改变了。当然,存在一些特殊情况。
const promise = new Promise(function(resolve, reject){
    resolve('ok');
    throw new Error();
});
promise.then(value=>console.log('-data----'+value),err=>console.log('-err-----'+err));//-data----ok

上面的函数结果为resolve,因为resolve函数在error的上面,虽然没有执行,但是promise实例对象的状态已经被改变为resolved

reject函数的执行或是err事件的发生,都会导致promise实例对象的状态变为rejected

const promise = new Promise(function(resolve, reject){
    throw new Error();
    resolve('ok');
});
promise.then(value=>console.log('-data----'+value),err=>console.log('-err-----'+err));-err-----Error

注意,then方法在当前所有同步脚本执行之后执行。

let promise = new Promise(function(resolve, reject) {
  console.log('Promise');
  resolve();
});

promise.then(function() {
  console.log('resolved.');
});

console.log('Hi!');

// Promise
// Hi!
// resolved

3. 实例的状态产生了。

实例的状态是在当给resolve或reject的操作传入参数完毕,或者出现未捕获的错误时产生。

让我们来看一段代码

const promise = new Promise(function(resolve, reject){
  setTimeout(() => {
    console.log("resolve还没开始:",promise);
  }, 5000)
  setTimeout(() => {
  	resolve('ok');
    console.log("resolve刚刚结束:",promise);
  }, 6000)
});
promise.then(result=>{
  console.log(result)
});

在这里插入图片描述

大家可以看到

  • 在resolve执行之前
    [[PromiseStatus]]:“pending”
    [[PromiseValue]]:undefined
  • 在resolve执行之后
    [[PromiseStatus]]:“resolved”
    [[PromiseValue]]:“ok”

这说明,在resolve执行之后,promise会存下状态和对应的参数。

了解了上面的知识,我们来看看下面这个例子

const p1 = new Promise(function (resolve, reject) {
  setTimeout(() => reject(new Error('fail')), 3000)
})
 
const p2 = new Promise(function (resolve, reject) {
  setTimeout(() => resolve(p1), 1000)
})

p2
  .then(result => {
console.log("成功");
console.log("p2:",p2);
console.log("p1:",result)})
  .catch(error =>{ 
console.log("失败");
console.log("p2",p2);
console.log("p1",p1);
});

猜测一下打出来的结果是什么呢?

失败
p2 Promise {
  <rejected> Error: fail
      at Timeout.setTimeout [as _onTimeout] (G:\WebstormProjects\es6\11_promise.js:25:27)
      at ontimeout (timers.js:436:11)
      at tryOnTimeout (timers.js:300:5)
      at listOnTimeout (timers.js:263:5)
      at Timer.processTimers (timers.js:223:10) }
p1 Promise {
  <rejected> Error: fail
      at Timeout.setTimeout [as _onTimeout] (G:\WebstormProjects\es6\11_promise.js:25:27)
      at ontimeout (timers.js:436:11)
      at tryOnTimeout (timers.js:300:5)
      at listOnTimeout (timers.js:263:5)
      at Timer.processTimers (timers.js:223:10) }

上面代码中,p1是一个 Promise,3 秒之后变为rejected。p2的状态在 1 秒之后改变,此时本应该执行then方法中的成功回调函数了,但是由于resolve方法返回的是p1,另一个 Promise,导致p2自己的状态无效了,于是我们根本没有进p2的成功回调。而是由p1的状态决定p2的状态。所以,后面的then语句都变成针对后者(p1)。又过了 2 秒,p1变为rejected,导致触发catch方法指定的回调函数。这也可以解释,为什么最后打出来的p1和p2的状态都是reject。

如果看到上述代码还是不太明白,Promise.resolve或许能让你理解的更清楚一些

4.Promise.resolve

看到Promise.resove的时候,大家可能会有一点奇怪,resolve分明是promise实例成功的回调函数啊,怎么又和Promise构造函数扯上关系了呢?

有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用。

Promise.resolve等价于下面的写法。

Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))

但是存在差别,new Promise是等实例对象执行完之后把值和状态拷贝过来,Promise.resolve则是返回了同一份实例对象。

参照阮一峰的说法,Promise.resolve方法的参数分成四种情况。

(1)参数是一个 Promise 实例

如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

const p1 = new Promise(function (resolve, reject) {
	resolve('ok');  
})
var p2 = Promise.resolve(p1);

console.log(p2);
VM335:6 Promise {<resolved>: "ok"}

大家请仔细观察:

var p2 = Promise.resolve(p1);
等价于=>
var p2 = new Promise(resolve => resolve(p1))

是不是和上面的

const p2 = new Promise(function (resolve, reject) {
  setTimeout(() => resolve(p1), 1000)
})

十分相似呢??

这就能解释,为啥上面的那个问题中,p2的状态无效了。因为resolve的参数是p1,所以Promise.resolve将p1原封不动的返回了,p2的状态被重置为了p1的状态,因此p2状态无效。

(2)参数不是具有then方法的对象,或根本就不是对象

如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved。

  • 不具有then方法的对象
var obj  = {name:'kk'}
const a = Promise.resolve(obj);
等价于=>
const a = new Promise(resolve=>resolve(obj);)
console.log(a);

Promise {<resolved>: {}}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: Object
name: "kk"
__proto__: Object
  • 原始值
var obj = 'kk'
var a = Promise.resolve(obj);
console.log(a);

Promise {<resolved>: "kk"}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: "kk"

根据以上,Promise.resolve可以将一个没有then方法的对象/原始值转换为一个[[PromiseStatus]]: “resolved”,[[PromiseValue]]为没有then方法的对象/原始值的promise实例。

(3)参数是一个thenable对象

thenable对象指的是具有then方法的对象,比如下面这个对象。

let thenable = {
  then: function(resolve, reject) {
    console.log('aa');
    resolve(42);
  }
};

Promise.resolve方法会将这个对象转为 Promise 对象,并且立即执行thenable对象的then方法。这里的自动调用的then方法起到的作用,并不像promise实例中用来传递成功和失败回调函数的手动调用的then方法,反而更像创建promise实例的时候,传入Promise构造函数中的那个函数

let p1 = Promise.resolve(thenable);
//aa
console.log(p1);

上面代码中,thenable对象的自动执行的then方法执行后,对象p1的状态就变为resolved,值变为42,然后我们可以通过手动执行的then方法给promise实例传入成功回调函数。

p1.then(()=>console.log('ok'))
// ok

对于thenable对象而言,即使执行了Promise.resolve,它的状态也不一定为resove

var obj = {
  then:function(resolve,reject){
    reject('okkkk');
  }
}
p = Promise.resolve(obj);
console.log(p)

Promise {<rejected>: "okkkk"}
__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: "okkkk"
(4)不带有任何参数

Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。

所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve()方法。

const p = Promise.resolve();
console.log(p)

Promise {<resolved>: undefined}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: undefined
因此,我们可以如此简化记忆,promise.resolve的参数有两种情况
  • promise实例,直接返回,状态由返回的实例决定
  • 非promise实例,执行了resolve之后状态为resolve,否则状态为pending,值为resolve传入的值,没有值为undefined,存在then方法的话需要在then方法中手动调用resolve改变实例状态,不存在then方法会自动把实例状态设为resolve。

5.Promise.reject

Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))

p.then(null, function (s) {
  console.log(s)
});
// 出错了

上面代码生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行。

注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致。

const thenable = {
  then(resolve, reject) {
    reject('出错了');
  }
};

var p1 = Promise.reject(thenable);
p1.catch(e => {
  console.log(e === thenable)
})
// true

上面代码中,Promise.reject方法的参数是一个thenable对象,执行以后,后面catch方法的参数不是reject抛出的“出错了”这个字符串,而是thenable对象。

6.Promise.catch()

Promise.prototype.catch方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

p.then((val) => console.log('fulfilled:', val))
  .catch((err) => console.log('rejected', err));

// 等同于
p.then((val) => console.log('fulfilled:', val))
  .then(null, (err) => console.log("rejected:", err));

Promise.catch在三种情况下会被触发

  • promise实例创建时产生错误
const p = new Promise((resolve, reject) =>{ 
  throw new Error();
})
p.catch(e=>{
  console.log(p);
})


Promise {
  <rejected> Error
      at Promise (G:\WebstormProjects\es6\11_promise.js:95:9)
      at new Promise (<anonymous>)
      at Object.<anonymous> (G:\WebstormProjects\es6\11_promise.js:94:11)
      at Module._compile (internal/modules/cjs/loader.js:701:30)
      at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
      at Module.load (internal/modules/cjs/loader.js:600:32)
      at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
      at Function.Module._load (internal/modules/cjs/loader.js:531:3)
      at Function.Module.runMain (internal/modules/cjs/loader.js:754:12)
      at startup (internal/bootstrap/node.js:283:19) }
  • promise实例状态变为rejected时
const p = new Promise((resolve, reject) =>{ 
  reject('as');
})
p.catch(e=>{
  console.log(p);
})

Promise { <rejected> 'as' }
  • catch前面所有的then方法和catch方法执行过程中产生的错误
var p1 = new Promise((resolve,reject)=>{
  throw new Error('干嘛鸭,我是p1')
  resolve("我是快乐的p1");
})
var p2  = new Promise((resolve,reject)=>{
  throw new Error('气死死了,我是p2');
  resolve('开心,我是p2');
})
var p3 = Promise.resolve('该死,我是p3');
p3.then(result=>{
console.log(result);
 return p2;
}).then(result=>{
  console.log(result);
  return p1;
}).then(result=>{
  console.log(result);
  throw new Error("人生处处是错误");
}).catch(err=>{
  console.log(err);
  throw new Error("哼,没有人能捕获到我");
})

该死,我是p3
Error: 气死死了,我是p2

p2的错误被捕获了,接下来,我们把p2的错误注释了

var p2  = new Promise((resolve,reject)=>{
  //throw new Error('气死死了,我是p2');
   resolve('开心,我是p2');
})

该死,我是p3
开心,我是p2
Error: 干嘛鸭,我是p1

又捕获到了p1的错误。我们再把p1的错误注释了

var p1 = new Promise((resolve,reject)=>{
  //throw new Error('干嘛鸭,我是p1')
  resolve("我是快乐的p1");
})

该死,我是p3
开心,我是p2
我是快乐的p1
Error: 人生处处是错误

又捕获到了p1的回调中出现的错误,我们把p1回调中的错误注释了

该死,我是p3
开心,我是p2
我是快乐的p1

错误消失了。

注意

1. catch只捕获在自己前面产生的错误,并不捕获本次catch产生的错误,要想对本次catch产生的错误进行捕获,需要在本次catch后再写一个catch进行错误捕获。
catch(err=>{
  console.log(err);
  throw new Error("哼,没有人能捕获到我");
})

大家看,在最后一个catch中的错误,没有人能捕获到!没事,我们可以在catch后面再加一个catch

catch(err=>{
  console.log(err);
  throw new Error("哼,没有人能捕获到我");
}).catch(err=>{
  console.log("别以为我抓不到你:"+err);
})

该死,我是p3
开心,我是p2
我是快乐的p1

欸?怎么没捕获到?这是因为,没有错误产生,所以catch没有执行,让我们把随便一个错误的注释取消

then(result=>{
  console.log(result);
  throw new Error("人生处处是错误");
}

该死,我是p3
开心,我是p2
我是快乐的p1
Error: 人生处处是错误
    at p3.then.then.then.result (G:\WebstormProjects\es6\11_promise.js:134:9)
    at process._tickCallback (internal/process/next_tick.js:68:7)
    at Function.Module.runMain (internal/modules/cjs/loader.js:757:11)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
别以为我抓不到你:Error:,没有人能捕获到我

很愉快的报错了!

2. catch捕获错误的顺序按照从前往后的方式,如果已经捕获到前面的错误,就不会对后面的错误进行捕获了
3. 如果状态已经变为resolve,那么catch就不会进行错误捕获

我们稍微修改一下p1

var p1 = new Promise((resolve,reject)=>{
  resolve("我是快乐的p1");
  throw new Error('干嘛鸭,我是p1')
})

该死,我是p3
开心,我是p2
我是快乐的p1
Error: 人生处处是错误
    at p3.then.then.then.result (G:\WebstormProjects\es6\11_promise.js:136:9)
    at process._tickCallback (internal/process/next_tick.js:68:7)
    at Function.Module.runMain (internal/modules/cjs/loader.js:757:11)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
别以为我抓不到你:Error:,没有人能捕获到我

你看,p1的错误没有被捕获到!

7.Promise.finally()

finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。

8.Promise.all()

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

上面代码中,Promise.all方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例,如果不是,就会先调用上面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。(Promise.all方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。)

p的状态由所有数组成员决定,分成两种情况。

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。promise的状态变为resolved,promise实例的值依然为undefined

var p1 = Promise.resolve("a");
var p2 = Promise.resolve("b");
var p3 = Promise.resolve("c");
var p4 = Promies.reject("d");
var p5 = Promies.reject("e");


Promise.all([p1,p2,p3]).then(result=>{
    console.log("result",result);
}).catch(err=>{
    console.log("err",err);
})

//result ["a", "b", "c"]
Promise
__proto__:Promise
[[PromiseStatus]]:"resolved"
[[PromiseValue]]:undefined

(2)只要p1、p4、p5之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。此时promise实例的状态变为了rejected,promise的值也变为了第一个状态变为rejected的promise实例的值。

Promise.all([p1,p4,p5]).then(result=>{
    console.log("result",result);
}).catch(err=>{
    console.log("err",err);
})

//err d
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: undefined}//Promise
__proto__:Promise
[[PromiseStatus]]:"rejected"
[[PromiseValue]]:"d"
注意
  • 如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。
  • Promise.all数组中的每一个promise是并行执行,没有先后顺序之分。

9.Promise.race()

Promise.race方法的参数与Promise.all方法一样,如果不是 Promise 实例,就会先调用上面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。

const p = Promise.race([p1, p2, p3]);

上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

10. Promise可以采用链式写法

promise之所以能采用链式写法,是因为,promise的catch,then,finally等方法的返回值都是promise实例。但是,他们的返回值之间又存在着差别。

1.对于catch和then

promise实例的catch和then方法的返回值,是一个新的promise实例。

var a = Promise.resolve("我是a的值");
var returnValue = a.then(result=>console.log(result));

a
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: "我是a的值"

returnValue
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: undefined

var a = Promise.resolve("我是a的值");
var returnValue = a.then(result=>{
	console.log(result)
	throw new Error();
});

returnValue
__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: Error at <anonymous>:3:8

var b = Promise.reject("我是b的值");
var returnValue1 = b.catch(err=>console.log(err));

b
__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: "我是b的值"

returnValue1
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: undefined

var b = Promise.reject("我是b的值");
var returnValue1 = b.catch(err=>{
	console.log(err)
	throw new Error();
});

returnValue1
__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: Error at <anonymous>:3:8

显然,新的promise实例的状态和原promise实例状态无关,而是取决于原promise实例在执行catch和then方法中有没有发生错误。
这个新的promise实例的值分为两种情况

  • 当promise实例没有报错,最后的状态变为resolve,如果then/catch方法中没有显式返回,那么新promise实例的值为undefined。否则值为显式返回的那个值
var returnValue = a.then(result=>{
	console.log(result)
//	throw new Error();
});

returnValue
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: undefined

var returnValue = a.then(result=>{
	console.log(result)
//	throw new Error();
	return 1;
});

returnValue
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: 1
  • 当新promise实例报错,状态变为reject,新promise实例的返回值为报错的值,无需显式返回,即使显式返回,也不会改变新promise实例的值。
var returnValue = a.then(result=>{
	console.log(result)
	throw new Error();
	return 1;
});

returnValue
__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: Error at <anonymous>:3:8
2.对于finally而言

finally的返回值也是一个promise实例

var returnValue1 = a.finally(()=>{
});
returnValue1
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: "我是a的值"

returnValue1 === a
false

returnValue1 = b.finally(()=>{
})


returnValue1
__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: "我是b的值"
returnValue1 === b
false

var returnValue1 = a.finally(()=>{
	throw new Error();
});

returnValue1
Promise {<rejected>: Error
    at <anonymous>:3:8
    at <anonymous>}

returnValue1 = a.finally(()=>{
	return 1;
});

returnValue1
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: "我是a的值"

b也如此,已试验

由上,当finally方法中传入的回调函数没有报错时,finally返回的新实例会继承原promise实例的状态和值,当finally中传入的回调函数报错,finally返回的新实例的状态为"rejected",值为错误原因。回调中的显式返回对finally不起作用
对于回调函数中显示返回的探究,让我不禁有了更大胆的猜测——他们的返回值是如何起作用的呢?我猜测,报错时,把值传进Promise.reject中,没有报错时,把值传进Promise.resolve
在上面Promise.resolve的学习中,我们可以知道,如果Promise.resolve方法传进一个有then方法的实例,那么它会立刻执行,我们可以通过这一点来猜测它们的返回值是否是通过Promise.resolve创建新promise实例的。

var obj= {
    then:function(){
	console.log('ok');
}}
var returnValue1 = a.finally(()=>{
	return obj;
});
//ok
var returnValue1 = a.then(()=>{
	return obj;
});
//ok
var returnValue1 = b.catch(()=>{
	return obj;
});
//ok

我的猜测果然没错,这些回调函数return的值,都被传入了Promise.resolve函数中进行处理,然后返回新的promise实例。
那么我们如何解释then,catch,finally返回的promise实例的差异呢?我个人觉得可以这样解释

  • 当then和catch的return值不存在时,实际上是用Promise.resolve()创建了一个新的promise实例对象,而对finally来说,是用Promise.resolve(原promsie实例的副本)创建了一个新的promise实例对象。
  • 当then和catch的return值存在时,用Promise.resolve(return值)创建了一个新的promise实例对象,而对finally来说,还需要判断return的值上面有没有存在then方法,如果存在的话就用Promise.resolve(return值)创建一个新的promise实例对象,否则依然用promise.resolve(原实例的副本)创建一个新的promise实例对象。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值