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

ECMAScript 6 Promise对象

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

resource-that-may-take-a-while'), new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('request timeout')), 5000) })])p.then(response => console.log(response))p.catch(error => console.log(error))上面代码中,如果5秒之内fetch方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数。Promise.resolve()有时需要将现有对象转为Promise对象,Promise.resolve方法就起到这个作用。var jsPromise = Promise.resolve($.ajax('/whatever.json'));上面代码将jQuery生成的deferred对象,转为一个新的Promise对象。Promise.resolve等价于下面的写法。Promise.resolve('foo')// 等价于new Promise(resolve => resolve('foo'))Promise.resolve方法的参数分成四种情况。(1)参数是一个Promise实例如果参数是Promise实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。(2)参数是一个thenable对象thenable对象指的是具有then方法的对象,比如下面这个对象。let thenable = { then: function(resolve, reject) { resolve(42); }};Promise.resolve方法会将这个对象转为Promise对象,然后就立即执行thenable对象的then方法。let thenable = { then: function(resolve, reject) { resolve(42); }};let p1 = Promise.resolve(thenable);p1.then(function(value) { console.log(value); // 42});上面代码中,thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出42。(3)参数不是具有then方法的对象,或根本就不是对象如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的Promise对象,状态为Resolved。var p = Promise.resolve('Hello');p.then(function (s){ console.log(s)});// Hello上面代码生成一个新的Promise对象的实例p。由于字符串Hello不属于异步操作(判断方法是它不是具有then方法的对象),返回Promise实例的状态从一生成就是Resolved,所以回调函数会立即执行。Promise.resolve方法的参数,会同时传给回调函数。(4)不带有任何参数Promise.resolve方法允许调用时不带参数,直接返回一个Resolved状态的Promise对象。所以,如果希望得到一个Promise对象,比较方便的方法就是直接调用Promise.resolve方法。var p = Promise.resolve();p.then(function () { // ...});上面代码的变量p就是一个Promise对象。需要注意的是,立即resolve的Promise对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。setTimeout(function () { console.log('three');}, 0);Promise.resolve().then(function () { console.log('two');});console.log('one');// one// two// three上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log(’one‘)则是立即执行,因此最先输出。Promise.reject()Promise.reject(reason)方法也会返回一个新的Promise实例,该实例的状态为rejected。它的参数用法与Promise.resolve方法完全一致。var p = Promise.reject('出错了');// 等同于var p = new Promise((resolve, reject) => reject('出错了'))p.then(null, function (s){ console.log(s)});// 出错了上面代码生成一个Promise对象的实例p,状态为rejected,回调函数会立即执行。两个有用的附加方法ES6的Promise API提供的方法不是很多,有些有用的方法可以自己部署。下面介绍如何部署两个不在ES6之中、但很有用的方法。done()Promise对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到(因为Promise内部的错误不会冒泡到全局)。因此,我们可以提供一个done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。asyncFunc() .then(f1) .catch(r1) .then(f2) .done();它的实现代码相当简单。Promise.prototype.done = function (onFulfilled, onRejected) { this.then(onFulfilled, onRejected) .catch(function (reason) { // 抛出一个全局错误 setTimeout(() => { throw reason }, 0); });};从上面代码可见,done方法的使用,可以像then方法那样用,提供Fulfilled和Rejected状态的回调函数,也可以不提供任何参数。但不管怎样,done都会捕捉到任何可能出现的错误,并向全局抛出。finally()finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。它与done方法的最大区别,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。下面是一个例子,服务器使用Promise处理请求,然后使用finally方法关掉服务器。server.listen(0) .then(function () { // run test }) .finally(server.stop);它的实现也很简单。Promise.prototype.finally = function (callback) { let P = this.constructor; return this.then( value => P.resolve(callback()).then(() => value), reason => P.resolve(callback()).then(() => { throw reason }) );};上面代码中,不管前面的Promise是fulfilled还是rejected,都会执行回调函数callback。应用加载图片我们可以将图片的加载写成一个Promise,一旦加载完成,Promise的状态就发生变化。const preloadImage = function (path) { return new Promise(function (resolve, reject) { var image = new Image(); image.onload = resolve; image.onerror = reject; image.src = path; });};Generator函数与Promise的结合使用Generator函数管理流程,遇到异步操作的时候,通常返回一个Promise对象。function getFoo () { return new Promise(function (resolve, reject){ resolve('foo'); });}var g = function* () { try { var foo = yield getFoo(); console.log(foo); } catch (e) { console.log(e); }};function run (generator) { var it = generator(); function go(result) { if (result.done) return result.value; return result.value.then(function (value) { return go(it.next(value)); }, function (error) { return go(it.throw(error)); }); } go(it.next());}run(g);上面代码的Generator函数g之中,有一个异步操作getFoo,它返回的就是一个Promise对象。函数run用来处理这个Promise对象,并调用下一个next方法。

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


ECMAScript 6 Promise对象