当前位置:K88软件开发文章中心编程语言JavaScriptECMAScript → 文章内容

ECMAScript 6 Promise对象

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 15:38:38

写法(try/catch)。因此,建议总是使用catch方法,而不使用then方法的第二个参数。跟传统的try/catch代码块不同的是,如果没有使用catch方法指定错误处理的回调函数,Promise对象抛出的错误不会传递到外层代码,即不会有任何反应。var someAsyncThing = function() { return new Promise(function(resolve, reject) { // 下面一行会报错,因为x没有声明 resolve(x + 2); });};someAsyncThing().then(function() { console.log('everything is great');});上面代码中,someAsyncThing函数产生的Promise对象会报错,但是由于没有指定catch方法,这个错误不会被捕获,也不会传递到外层代码,导致运行后没有任何输出。注意,Chrome浏览器不遵守这条规定,它会抛出错误“ReferenceError: x is not defined”。var promise = new Promise(function(resolve, reject) { resolve("ok"); setTimeout(function() { throw new Error('test') }, 0)});promise.then(function(value) { console.log(value) });// ok// Uncaught Error: test上面代码中,Promise指定在下一轮“事件循环”再抛出错误,结果由于没有指定使用try...catch语句,就冒泡到最外层,成了未捕获的错误。因为此时,Promise的函数体已经运行结束了,所以这个错误是在Promise函数体外抛出的。Node.js有一个unhandledRejection事件,专门监听未捕获的reject错误。process.on('unhandledRejection', function (err, p) { console.error(err.stack)});上面代码中,unhandledRejection事件的监听函数有两个参数,第一个是错误对象,第二个是报错的Promise实例,它可以用来了解发生错误的环境信息。。需要注意的是,catch方法返回的还是一个Promise对象,因此后面还可以接着调用then方法。var someAsyncThing = function() { return new Promise(function(resolve, reject) { // 下面一行会报错,因为x没有声明 resolve(x + 2); });};someAsyncThing().catch(function(error) { console.log('oh no', error);}).then(function() { console.log('carry on');});// oh no [ReferenceError: x is not defined]// carry on上面代码运行完catch方法指定的回调函数,会接着运行后面那个then方法指定的回调函数。如果没有报错,则会跳过catch方法。Promise.resolve().catch(function(error) { console.log('oh no', error);}).then(function() { console.log('carry on');});// carry on上面的代码因为没有报错,跳过了catch方法,直接执行后面的then方法。此时,要是then方法里面报错,就与前面的catch无关了。catch方法之中,还能再抛出错误。var someAsyncThing = function() { return new Promise(function(resolve, reject) { // 下面一行会报错,因为x没有声明 resolve(x + 2); });};someAsyncThing().then(function() { return someOtherAsyncThing();}).catch(function(error) { console.log('oh no', error); // 下面一行会报错,因为y没有声明 y + 2;}).then(function() { console.log('carry on');});// oh no [ReferenceError: x is not defined]上面代码中,catch方法抛出一个错误,因为后面没有别的catch方法了,导致这个错误不会被捕获,也不会传递到外层。如果改写一下,结果就不一样了。someAsyncThing().then(function() { return someOtherAsyncThing();}).catch(function(error) { console.log('oh no', error); // 下面一行会报错,因为y没有声明 y + 2;}).catch(function(error) { console.log('carry on', error);});// oh no [ReferenceError: x is not defined]// carry on [ReferenceError: y is not defined]上面代码中,第二个catch方法用来捕获,前一个catch方法抛出的错误。Promise.all()Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。var p = Promise.all([p1, p2, p3]);上面代码中,Promise.all方法接受一个数组作为参数,p1、p2、p3都是Promise对象的实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为Promise实例,再进一步处理。(Promise.all方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是Promise实例。)p的状态由p1、p2、p3决定,分成两种情况。(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。下面是一个具体的例子。// 生成一个Promise对象的数组var promises = [2, 3, 5, 7, 11, 13].map(function (id) { return getJSON("/post/" + id + ".json");});Promise.all(promises).then(function (posts) { // ...}).catch(function(reason){ // ...});上面代码中,promises是包含6个Promise实例的数组,只有这6个实例的状态都变成fulfilled,或者其中有一个变为rejected,才会调用Promise.all方法后面的回调函数。下面是另一个例子。const databasePromise = connectDatabase();const booksPromise = databaseProimse .then(findAllBooks);const userPromise = databasePromise .then(getCurrentUser);Promise.all([ booksPromise, userPromise]).then(([books, user]) => pickTopRecommentations(books, user));上面代码中,booksPromise和userPromise是两个异步操作,只有等到它们的结果都返回了,才会触发pickTopRecommentations这个回调函数。Promise.race()Promise.race方法同样是将多个Promise实例,包装成一个新的Promise实例。var p = Promise.race([p1,p2,p3]);上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的回调函数。Promise.race方法的参数与Promise.all方法一样,如果不是Promise实例,就会先调用下面讲到的Promise.resolve方法,将参数转为Promise实例,再进一步处理。下面是一个例子,如果指定时间内没有获得结果,就将Promise的状态变为reject,否则变为resolve。var p = Promise.race([ fetch('/

上一页  [1] [2] [3] [4]  下一页


ECMAScript 6 Promise对象