Bluebird警告:承诺是在处理程序中创建的,但未从中返回

时间:2016-04-28 18:57:06

标签: node.js promise bluebird async.js

我有一个文件名数组,我使用这个节点的异步模块进行迭代。

       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,但在我的案例中说得不够充分。 Atleast有办法关闭警告吗?

更新

请检查下面的正确答案,以及我的通话功能如何:

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);
            });
        }

2 个答案:

答案 0 :(得分:4)

如果您尝试将异步库回调与promises混合使用,那么您会遇到麻烦并抛弃编程优势。选择一个结构或另一个结构并在任何地方使用它。就个人而言,我建议你转向承诺,只是“promisify”功能,目前使用回调。如果您正在使用Bluebird Promise库,那么它具有Promise.promisify()Promise.promisifyAll(),这使得使用标准node.js异步回调的东西变得非常容易,因此您可以使用Promise逻辑控制所有内容

现在,针对您的具体问题。该错误意味着您正在.then()处理程序中创建promise,但这些promise不会返回或链接到任何先前的promise。因此,它们完全独立于您的其他链条。这通常是一个错误(因此是警告的原因)。一个人可能真正想要做的唯一一次是你有一些火灾和忘记操作,你不希望外部承诺等待,你没有跟踪错误,而不是你在这里的错误。

更改为:

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;
  });
}

的变化:

  1. 返回主要承诺,而不是创造新的承诺。
  2. 不需要return new Promise.resolve(res);,因为res已经从该承诺返回,因此您可以删除整个.then()处理程序,因为它没有执行任何操作。
  3. 不需要return new Promise.resolve(result);,因为您可以直接返回先前的承诺。
  4. 仅供参考,虽然您根本不需要它,Promise.resolve()可以在没有new的情况下直接调用。

答案 1 :(得分:0)

这里有一些问题:

 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 ),只需返回已经是Promise的result。中间人then也毫无意义。您可以将该代码减少为:

return imageStores.updateAsync(condArr, values, { upsert: true })
  .catch( function(err){
      logger.error(err);
  } )
;