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