ES6承诺解决callback?

我想运行相同的行动,无论我的Promise是否成功解决。 我不想将相同的函数绑定到.then两个参数上。 是不是像jQuery一样。 如果不是,我该如何做到这一点?

是不是像jQuery一样。

不, 还没有(还) 。 虽然有一个积极的build议 ,也许ES2018。

如果不是,我该如何做到这一点?

你可以像这样自己实现finally方法:

 Promise.prototype.finally = function(cb) { const res = () => this const fin = () => Promise.resolve(cb()).then(res) return this.then(fin, fin); }; 

或者更广泛地将分辨率信息传递给callback:

 Promise.prototype.finally = function(cb) { const res = () => this return this.then(value => Promise.resolve(cb({state:"fulfilled", value})).then(res) , reason => Promise.resolve(cb({state:"rejected", reason})).then(res) ); }; 

两者都确保原始分辨率得以维持(callback中没有例外),并且正在等待承诺。

与asynchronous/等待,你可以结合await try/finally ,如下所示:

 async function(somePromise) { try { await somePromise(); } finally { // always run this-- even if `somePromise` threw something } } 

下面是我使用Babel的asynchronous生成插件在Node中运行的一个真实示例。

 // Wrap promisified function in a transaction block export function transaction(func) { return db.sequelize.transaction().then(async t => { Sequelize.cls.set('transaction', t); try { await func(); } finally { await t.rollback(); } }); } 

我将这段代码与Sequelize ORM一起用于摩卡testing,以启动数据库事务,不pipetesting中数据库调用的结果如何,总是在最后回滚。

这大致类似于Bluebird的.finally()方法,但IMO,更好的语法!

注意 :如果您想知道为什么我没有await第一个Promise,那么它就是Sequelize的实现细节,它使用CLS将SQL事务绑定到Promise链上。因为等待Promise会“closures”事务处理块并断开连锁,我将这个例子展示给你看,如何将“vanilla”Promise处理与asynchronous混合在一起function,并且一起玩。)

如果你没有/不能更新原型,最后的破解方式是:

 executeMyPromise() .then(function(res){ return {res: res}; }) .catch(function(err){ return {err: err}; }) .then(function(data) { // do finally stuff if (data.err) { throw data.err; } return data.res; }).catch(function(err) { // handle error }); 

这是我的.finally()的实现。

 Promise.prototype.finally = function(cb) { return this.then(v=>Promise.resolve(cb(v)), v=>Promise.reject(cb(v))); }; 

我testing了它:

 (new Promise((resolve,reject)=>{resolve(5);})).finally(x=>console.log(x)); //5 (new Promise((resolve,reject)=>{reject(6);})).finally(x=>console.log(x)); //6 (new Promise((resolve,reject)=>{reject(7);})) .then(x=>x,y=>y) .catch(x=>{throw "error";}) .finally(x=>{console.log(x); throw "error"; return x;}) // 7 .then(x=>console.log(x),y=>console.log('e')); //e // Uncaught (in promise) undefined