【问题标题】:Bluebird Warning : a promise was created in a handler but was not returned from it蓝鸟警告:在处理程序中创建了一个承诺,但没有从它返回
【发布时间】:2016-08-23 17:25:46
【问题描述】:

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

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

【问题讨论】:

  • 不要将async.js 与承诺一起使用!
  • @Bergi 我会遇到这个问题吗?我都是新手,请指教?
  • 是的,你会的,诸如此类的问题。而且处理错误会变得更加复杂,return 在适当的地方承诺,如果你将它们与节点样式的回调混合,则可以轻松地链接承诺。只是不要。 Bluebird 在其工具套件中拥有您需要的一切。在您的情况下,Promise.eachPromise.mapSeries

标签: node.js promise bluebird async.js


【解决方案1】:

如果您尝试将异步库回调与 Promise 混合使用,您就是在自找麻烦并放弃编程优势。选择一种或另一种结构并在任何地方使用它。就个人而言,我建议你转向承诺,只是“承诺”目前与回调一起工作的函数。如果您使用的是 Bluebird Promise 库,那么它有 Promise.promisify()Promise.promisifyAll() 可以很容易地承诺使用标准 node.js 异步回调的东西,因此您可以使用 Promise 逻辑控制一切。

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

改成这样:

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);,因为您可以直接返回之前的承诺。

仅供参考,虽然您在这里根本不需要它,但可以直接调用 Promise.resolve() 而无需 new

【讨论】:

  • 哦,稍微改变一下就行了。也删除了调用函数的 .then() 部分。
  • @swatek - 然后,错误是由您可能没有向我们展示的更高或更低级别的东西触发的。修改后的updateCollection() 代码本身不会触发该错误。 updateCollection() 的调用方式或代码在 updateAsync() 内部的工作方式可能存在问题。
  • 请检查我所做的更新,现在可以使用,非常感谢! :)
  • 如果您不介意的建议 - 将 async 与 Promise 混合使用是个好主意吗?我应该坚持一个框架还是混合两者都可以?
  • @swatek - 我的回答的第一段已经说你不应该混合异步和承诺。馊主意。你只会让生活变得困难,容易产生错误,难以使用两者的最佳功能。
【解决方案2】:

这里有一些问题:

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

【讨论】:

  • @jfriend00 你几乎只是重复了我在回答中所说的一切......为什么不改为投票呢?
  • 是的,显然我误读了你所说的一些内容。但是您的 .catch() 处理程序是错误的。
  • @jfriend00 我不会说错的。我只是没有假设 OP 希望调用者看到拒绝。他是添加catch 的人,所以我假设记录该错误是他想要做的所有事情来处理它并且调用者没有任何东西要捕获。
  • 您假设 OP 不想返回拒绝,但希望拒绝变成具有 undefined 值的已解决承诺?有 99% 的可能性是错误。
猜你喜欢
  • 1970-01-01
  • 2016-09-20
  • 1970-01-01
  • 1970-01-01
  • 2017-11-02
  • 1970-01-01
  • 2016-03-01
  • 1970-01-01
  • 2016-10-18
相关资源
最近更新 更多