ES6 promise 如何调试
发布于 8 年前 作者 Pana 7943 次浏览 来自 问答

ES6 的promise很好用, 但似乎如果用法不对的话, 会有不少问题, 而promise的调试又及其麻烦, 因为根本没有stacktrace, 不知道有有哪个同学有好的办法不

相关的一篇文章: http://blog.soareschen.com/the-problem-with-es6-promises

15 回复

酒是好酒,就是后劲有点大

弱弱的问一句,stacktrace 的问题,用 bluebird 会好一点吗?我刚开始用 Promise

@alsotang 貌似大家都说bluebird更快, 而且还有stacktrace

和以前一样,debug 或者 console.log 查看then, catch 传入函数的值 我觉得Promise分支都是可预见的, 出错应该和Promise 无关(使用方法不对除外)

我用Promise 也不是太深,下面的资源应该能帮到你

这篇文章不错 http://efe.baidu.com/blog/promises-anti-pattern/

还有这个手册 http://liubin.github.io/promises-book/

我的经验是,promise一定要flat,千万不要嵌套,否则catch不住,每个then都要return,最后加catch,就能把所有的异常抓住,便于调试。 另外一个建议如果用了es6,何不就更上一层用generator+co了,我半年年之前都用promise,现在已经全部用yield了,非常爽。

@ron-liu 每个 then 都要 return?已经拿到数据的情况下,return 什么给后面呢?

promise + co 这点我很赞同,爽啊

原子化接口,做好单元测试。debug并不麻烦吧。

用bluebird, longStackTraces 如果没错误输出,检查是不是有promise没return

来自酷炫的 CNodeMD

@alsotang 没有return的话,是不是表面你后面的逻辑也可以写到当前的then里面?

@ron-liu 并不是。后面的逻辑从前后顺序上说,是要在当前 promise 完成之后做的。但后面的逻辑不是我决定的啊,我丢个 promise 给外面,外面接上的 then,我没法控制,也就没法加进当前 then 了。

@alsotang 哈哈,你这一点我猜我之前应该想到了,如果你要下面的then在本then的promise resolve后再做,那也要在本then中return 这个promise。而我们这个问题的前提是:如果本then中没有return。 我之前(现在也是)经常犯的错误是,在中间的then中没有return promise。比如: db.orders.query(…) .then(data=>{ return db.users.query({_id: data.userId}) // 此处如果不return,后面的then其实是毫无意义的 }) .then(user=>{ … })

@ron-liu 可能我们说的不是一回事

var user = db.users.find({xx}).then(function (user) {
  // do sth with user, but dont return
})

user.then(function () {
  website.recordLastLoginTime()
})

@alsotang 外面的逻辑也可以是个promise。在你的代码上做如下修改:

function temp(user){
	return new Promise((resolve, reject)=>{
		// 一些处理
		if(err){
			reject(err);
		}else{
			resolve();
		}
	});
}


var user = db.users.find({xx}).then(temp)

user.then(function () {
  website.recordLastLoginTime()
})

@alsotang 其实recordLastLoginTime()是可以写到上一个then里面去的,如: var user = db.users.find({xx}).then(function (user) { // do sth with user, but dont return website.recordLastLoginTime(); })

另外其实js里面如果不return,其实也return了undefined。

不过我懂你的意思了,你主要是认为then里面return不是必须的,我想是对的。:)

用co yield吧,爽得一b,配合express和mongoose。另外说一句,co最新版直接就是返回promise了,你想怎么then都行。 自豪地采用 CNodeJS ionic

回到顶部