JavaScriptPromise返回值详解
JavaScript Promise返回值详解
Promise回顾
Promise回调函数返回⾮Promise值
Promise回调函数返回Promise对象
Promise回调函数中抛出错误
总结
Promise回顾
Promise对象是JavaScript ES6标准中⼀个重要的内容,它是为了异步⽽⽣的,相⽐于经典的回调函数写法,在处理⼤量异步任务时使⽤Promise链在可读性上会远远优于回调函数导致的回调地狱,本⽂建⽴在读者已经对Promise有所了解的情况下,如果你还不了解Promise,可以参考MDN上的这篇⽂章。
下⾯我们先来简要回顾⼀下Promise对象的性质,如果你已经⾜够熟悉,请前往下⼀节内容。
Promise有三种状态,如果⽤Promise()构造器创建⼀个Promise对象,当被创建时,它的状态是pending,如果⼀个Promise对象的resolve⽅法被调⽤,它的状态会变成fulfilled,⽽如果⼀个Promise对象的reject⽅法被调⽤,它的状态会变成rejected。此外,还有两种初始化Promise对象的⽅法,分别是solve⽅法和ject⽅法,前者会直接返回⼀个状态为fulfilled的Promise对象⽽后者会直接返回⼀个状态为rejected的Promise对象。
在⼀个Promise链中,如果⼀个Promise状态变成了fulfilled,它会⾃动在Promise链中向下寻,直到发现⼀个then⽅法,并执⾏其中的第⼀个参数函数,⽽如果⼀个Promise的状态变成了rejected,它会在Promise链中向下寻,直到发现⼀个带有两个参数的then⽅法并执⾏它的第⼆个参数函数或发现⼀个catch⽅法并执⾏它的参数函数。
要知道,Promise.prototype.then和Promise.prototype.catch都会返回⼀个Promise对象,这是Promise链能⽣效的关键,这篇⽂章讨论的重点就是这两个⽅法的返回值。
注意:为了增强可读性,本⽂中涉及到Promise.prototype.then都只传⼊⼀个参数,作为fulfilled状态的回调函数,rejected状态的回调函数在Promise.prototype.catch中定义。
Promise回调函数返回⾮Promise值
当⼀个Promise.prototype.then⽅法被调⽤时,且在回调函数中返回的值是⼀个⾮Promise对象时,它会⽣成⼀个状态为fulfilled的新的Promise对象,并把该返回值传⼊下⼀个回调函数,看下⾯这个例⼦:
return 'Hello World';
})
.then(function(value) {
console.log(`fulfilled: ${value}`); // 'fulfilled: Hello World'
})
.catch(function(value) {
console.log(`rejected: ${value}`);
});
我们先⽤solve⽣成了⼀个fulfilled状态的Promise对象以便调⽤then⽅法,在它的回调函数中我们返回了⼀个字符串Hello World,可以看到Promise链中第⼆个then⽅法的回调函数被调⽤,打印出了fulfilled: Hello World,说明前⼀个回调函数的返回值被传⼊,且在Promise链的上⼀环节返回的新Promise状态为fulfilled。
当⼀个Promise.prototype.catch⽅法被调⽤,且在回调函数中返回的值是⼀个⾮Promise对象,它仍然会⽣成⼀个状态为fulfilled的新的Promise对象,并把该返回值传⼊下⼀个回调函数,相当于错误已经被捕获,看下⾯这个例⼦:
return 'Hello World';
})
.then(function(value) {
console.log(`fulfilled: ${value}`); // 'fulfilled: Hello World'
})
.catch(function(value) {
console.log(`rejected: ${value}`);
})
我们先⽤ject⽣成了⼀个rejected状态的Promise对象,这时第⼀个catch⽅法触发,在它的回调函数⾥返回了字符串Hello World,此后第⼀个then⽅法触发,打印出了fulfilled: Hello World,说明前⼀个回调函数的返回值被传⼊,且在Promise链的上⼀环节返回的新Promise状态为fulfilled。
你可以动⼿试试上⾯的例⼦,⾃⼰尝试着修改⼀些代码并查看返回值,有助于对这⼀节的内容有更深的理解。
Promise回调函数返回Promise对象
如果Promise的回调函数中返回的是Promise,那么⽆论触发的是Promise链中的then⽅法还是catch⽅法,新⽣成的Promise对象的状态都直接取决于
回调函数中返回的Promise对象的状态,传进下⼀个回调函数的值也取决于这个被返回的Promise对象,让我们看下⾯⼏个例⼦:
solve('Hello World');
})
.then(function(value) {
console.log(`fulfilled: ${value}`); // 'fulfilled: Hello World'
})
.catch(function(value) {
console.log(`rejected: ${value}`);
});
ject('Hello World');
})
.then(function(value) {
console.log(`fulfilled: ${value}`);
})
.catch(function(value) {
console.log(`rejected: ${value}`); // 'rejected: Hello World'
});
solve('Hello World');
})
.then(function(value) {
console.log(`fulfilled: ${value}`); // 'fulfilled: Hello World'
})
.catch(function(value) {
console.log(`rejected: ${value}`);
});
ject('Hello World');
})
.then(function(value) {
console.log(`fulfilled: ${value}`);
})
.
catch(function(value) {
console.log(`rejected: ${value}`); // 'rejected: Hello World'
});
你可以动⼿试试上⾯的例⼦来更深刻地感受⼀下返回Promise对象与返回其他值时的不同。
通过这⼏个例⼦可以看到,如果回调函数中返回Promise对象,⽆论是then⽅法还是catch⽅法⽣成的Promise对象都直接取决于回调函数中的这个Promise对象。
Promise回调函数中抛出错误
如果Promise的回调函数中抛出了⼀个错误,则会⽣成⼀个状态为rejected的Promise,并将这个错误作为参数传给Promise链的下⼀个回调函数,看下⾯两个例⼦:
throw new Error('Oops!');
})
.then(function(value) {
函数prototypeconsole.log('fulfilled');
console.ssage);
})
.catch(function(value) {
console.log('rejected'); // 'rejected'
console.ssage); // 'Oops!'
});
throw new Error('Oops!');
})
.
then(function(value) {
console.log('fulfilled');
console.ssage);
})
.catch(function(value) {
console.log('rejected'); // 'rejected'
console.ssage); // 'Oops!'
})
你可以动⼿试试来感受⼀下这种情况下抛出错误对⽣成的Promise对象的影响。
可以看到,这种情况下catch的回调函数被执⾏,说明抛出错误后,返回的Promise状态是rejected,并且传⼊Promise链下⼀环节的值是这个错误对象。
总结
当Promise的回调函数返回⾮Promise对象的值时,then和catch都⽣成⼀个状态为fulfilled的Promise对象,并把该返回值传⼊Promise链的下⼀环节。当Promise的回调函数返回值为Promise对象时,⽣成的Promise对象的状态由被返回的Promise对象决定,传⼊Promise链下⼀环节的值也由这个被返回的Promise决定。
当Promise的回调函数中抛出错误时,then和catch都⽣成⼀个状态为rejected的Promise对象,并把抛出的错误对象传⼊Promise链的下⼀环节。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论