bluebird从3.x开始对promise的错误使用会有以下三种Warning,提醒你正在不正确使用bluebird,下面对这三种warning进行解释,并说明如何避免。
Warning: .then() only accepts functions
Warning: a promise was rejected with a non-error
Warning: a promise was created in a handler but none were returned from it
Warning: .then() only accepts functions
Warning: .then方法只接受function作为参数
如果你看到这样的提醒,说明你的代码运行结果不符合你的预期。最主要原因是传个.then()
的参数是一个函数的执行结果,而不是函数本身。
function processImage(image) {
// Code that processes image
}
getImage().then(processImage());
上面的方法就是调用processImage()
然后立刻将返回结果传给.then()
.这里传给.then()
的参数就是undefined
。
为解决这个问题,只要给.then()
传函数就可以了,就像这样:
getImage().then(processImage)
如果你有疑问为什么这里不直接简单粗暴地抛出TypeError,而是一个warning。因为Promises/A+标准规定对待错误使用时不予理睬。
Warning: a promise was rejected with a non-error
Warning: 一个promise拒绝时抛出了一个非Error值
由于JavaScript的历史错误,throw
可以抛出任何类型的值。Promises/A+选择继续沿用这个错误,所以promise是可以抛出一个非Error类型的值。
一个错误是一个继承于Error的对象。它至少需要有.stack
和.message
属性。因为错误通常会被根据它的不同来源而被分成不同等级,所以一个错误需要包含足够的信息,以让高级别的handler拥有足够的信息来生成一份有用的高级的错误报告。
因为所有的对象都支持拥有属性,你可能还会有疑问说,为什么一定要是一个Error对象而不能是一个普通的对象。一个错误对象除了要有这些属性,还有一个同样重要的特性就是自动采集stack trace。有了stack trace你才能容易的找到错误的来源。
你最好处理下这些warning,因为一个被拒绝的promise返回一个非Error,会导致调试非常艰难并且高成本。另外如果你拒绝一个promise只是使用最简陋的调用reject()
,这样你就没办法处理错误了,而且你只能告诉用户“有地方出错了”。
Warning: a promise was created in a handler but none were returned from it
Warning: 你创建了一个没有返回结果的promise
这通常说明你只是单单地忘记了声明return
,但却导致了该promise丢失,从而无法关联到promise链中。
例如:
getUser().then(function(user) {
getUserData(user);
}).then(function(userData) {
// userData is undefined
});
因为在第一个then里面,getUserData(user)
没有作为结果return,导致第二个then认为userData=undefined
并立即执行(因为没有声明return默认返回undefined
)。
解决这个问题,你只需要return这个promise:
getUser().then(function(user) {
return getUserData(user);
}).then(function(userData) {
// userData is the user's data
});
如果你知道你在做什么,并且不想看到warning,你只需要随便返回点什么,比如null
:
getUser().then(function(user) {
// 后台执行,不在乎运行结果
saveAnalytics(user);
// 返回一个非`undefined`的值,表示我们并没有忘记return
return null;
});
原文链接:http://bluebirdjs.com/docs/warning-explanations.html
推荐阅读:Bluebird promise 设置
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。