蓝鸟警告:在处理程序中创建了承诺,但未从中返回
Bluebird Warning : a promise was created in a handler but was not returned from it
我有一个文件名数组,我使用这个节点的异步模块对其进行迭代。
async.eachSeries(imageStore, function(imageDetails,callback){
mongoMan.updateCollection('imageStore',imageDetails,{_id: imageDetails.fileName}).then(function(res){
return callback(null, res);
}).catch(function(err){
logger.error(err);
return callback(err);
});
},function(err){
callback(null);
});
updateCollection()函数是这样的:
exports.updateCollection = function(collection, values, condArr){
var result = imageStores.updateAsync(condArr, values, { upsert: true }).then(function(res){
return new Promise.resolve(res);
}).catch(function(err){
logger.error(err);
});
return new Promise.resolve(result);
}
此代码运行良好,更新数据库和所有内容。但是我还是无法解决蓝鸟抛出的警告:
Warning: a promise was created in a handler but was not returned from it
at Object.exports.updateCollection (/home/swateek/Documents/codebase/poc/apps/webapp/server/components/mongodb/mongoConn.js:46:22)
at /home/swateek/Documents/codebase/poc/apps/webapp/server/components/imageStore.js:72:24
at /home/swateek/Documents/codebase/poc/apps/webapp/node_modules/async/lib/async.js:181:20
at iterate (/home/swateek/Documents/codebase/poc/apps/webapp/node_modules/async/lib/async.js:262:13)
已查找解决方案here,但对我来说这还不够有说服力。至少有办法关闭警告吗?
更新
请检查下面的正确答案,这是我的调用函数的样子:
function(callback){// post imageStore data to DB
async.eachSeries(imageStore, function(imageDetails,callback){
mongoMan.updateCollection('imageStore',imageDetails,{_id: imageDetails.fileName}).catch(function(err){
logger.error(err);
return callback(err);
});
return callback(null);
},function(err){
callback(null);
});
}
你这里有一些问题:
var result = imageStores.updateAsync(condArr, values, { upsert: true }).then(function(res){
return new Promise.resolve(res);
}).catch(function(err){
logger.error(err);
});
return new Promise.resolve(result);
首先:Promise.resolve
不是构造函数,因此不应与 new
一起使用。其次:调用 Promise.resolve( result )
根本没有意义,只需调用 return result
就已经是 Promise 了。中间 then
也是毫无意义的。您可以将该代码缩减为:
return imageStores.updateAsync(condArr, values, { upsert: true })
.catch( function(err){
logger.error(err);
} )
;
如果您尝试将异步库回调与 promises 混合使用,那么您是在自找麻烦并放弃编程优势。选择一种或另一种结构并在任何地方使用它。就我个人而言,我建议您转向 promises 和目前使用回调的 "promisify" 函数。如果你使用的是 Bluebird Promise 库,那么它有 Promise.promisify()
和 Promise.promisifyAll()
这使得使用标准 node.js 异步回调的东西很容易被承诺,所以你可以控制一切承诺逻辑。
现在,谈谈您的具体问题。该错误意味着您正在 .then()
处理程序中创建承诺,但这些承诺并未 return 链接或链接到任何先前的承诺。因此,它们完全独立于您的其他链。这通常是一个错误(因此是警告的原因)。人们可能真正想要这样做的唯一一次是你有一些你不想让外部承诺等待的操作,并且你没有跟踪你这里没有的错误。
改为:
exports.updateCollection = function(collection, values, condArr){
return imageStores.updateAsync(condArr, values, { upsert: true}).catch(function(err){
logger.error(err);
// rethrow error so the caller will see the rejection
throw err;
});
}
变化:
- Return 主要承诺而不是创建新承诺。
- 不需要
return new Promise.resolve(res);
,因为 res
已经从该承诺中 return 编辑,因此您可以删除整个 .then()
处理程序,因为它没有做任何事情。
- 不需要
return new Promise.resolve(result);
,因为您可以直接 return 之前的承诺。
仅供参考,虽然你在这里根本不需要它,但 Promise.resolve()
可以直接调用而无需 new
。
我有一个文件名数组,我使用这个节点的异步模块对其进行迭代。
async.eachSeries(imageStore, function(imageDetails,callback){
mongoMan.updateCollection('imageStore',imageDetails,{_id: imageDetails.fileName}).then(function(res){
return callback(null, res);
}).catch(function(err){
logger.error(err);
return callback(err);
});
},function(err){
callback(null);
});
updateCollection()函数是这样的:
exports.updateCollection = function(collection, values, condArr){
var result = imageStores.updateAsync(condArr, values, { upsert: true }).then(function(res){
return new Promise.resolve(res);
}).catch(function(err){
logger.error(err);
});
return new Promise.resolve(result);
}
此代码运行良好,更新数据库和所有内容。但是我还是无法解决蓝鸟抛出的警告:
Warning: a promise was created in a handler but was not returned from it
at Object.exports.updateCollection (/home/swateek/Documents/codebase/poc/apps/webapp/server/components/mongodb/mongoConn.js:46:22)
at /home/swateek/Documents/codebase/poc/apps/webapp/server/components/imageStore.js:72:24
at /home/swateek/Documents/codebase/poc/apps/webapp/node_modules/async/lib/async.js:181:20
at iterate (/home/swateek/Documents/codebase/poc/apps/webapp/node_modules/async/lib/async.js:262:13)
已查找解决方案here,但对我来说这还不够有说服力。至少有办法关闭警告吗?
更新
请检查下面的正确答案,这是我的调用函数的样子:
function(callback){// post imageStore data to DB
async.eachSeries(imageStore, function(imageDetails,callback){
mongoMan.updateCollection('imageStore',imageDetails,{_id: imageDetails.fileName}).catch(function(err){
logger.error(err);
return callback(err);
});
return callback(null);
},function(err){
callback(null);
});
}
你这里有一些问题:
var result = imageStores.updateAsync(condArr, values, { upsert: true }).then(function(res){
return new Promise.resolve(res);
}).catch(function(err){
logger.error(err);
});
return new Promise.resolve(result);
首先:Promise.resolve
不是构造函数,因此不应与 new
一起使用。其次:调用 Promise.resolve( result )
根本没有意义,只需调用 return result
就已经是 Promise 了。中间 then
也是毫无意义的。您可以将该代码缩减为:
return imageStores.updateAsync(condArr, values, { upsert: true })
.catch( function(err){
logger.error(err);
} )
;
如果您尝试将异步库回调与 promises 混合使用,那么您是在自找麻烦并放弃编程优势。选择一种或另一种结构并在任何地方使用它。就我个人而言,我建议您转向 promises 和目前使用回调的 "promisify" 函数。如果你使用的是 Bluebird Promise 库,那么它有 Promise.promisify()
和 Promise.promisifyAll()
这使得使用标准 node.js 异步回调的东西很容易被承诺,所以你可以控制一切承诺逻辑。
现在,谈谈您的具体问题。该错误意味着您正在 .then()
处理程序中创建承诺,但这些承诺并未 return 链接或链接到任何先前的承诺。因此,它们完全独立于您的其他链。这通常是一个错误(因此是警告的原因)。人们可能真正想要这样做的唯一一次是你有一些你不想让外部承诺等待的操作,并且你没有跟踪你这里没有的错误。
改为:
exports.updateCollection = function(collection, values, condArr){
return imageStores.updateAsync(condArr, values, { upsert: true}).catch(function(err){
logger.error(err);
// rethrow error so the caller will see the rejection
throw err;
});
}
变化:
- Return 主要承诺而不是创建新承诺。
- 不需要
return new Promise.resolve(res);
,因为res
已经从该承诺中 return 编辑,因此您可以删除整个.then()
处理程序,因为它没有做任何事情。 - 不需要
return new Promise.resolve(result);
,因为您可以直接 return 之前的承诺。
仅供参考,虽然你在这里根本不需要它,但 Promise.resolve()
可以直接调用而无需 new
。