Q承诺链接,错误处理程序不叫

问题描述:

考虑以下代码Q承诺链接,错误处理程序不叫

var tryWithoutReindexing = function(indexName, properties) { 
     var settings = properties["settings"]; 
     var mappings = properties["mappings"]; 
     return elastic.closeIndex(indexName) 
      .then(elastic.putSettings(indexName, settings)) 
      .then(elastic.putMapping(indexName, mappings)) 
      .then(elastic.openIndex(indexName)); 
}; 

而且拨打:

tryWithoutReindexing(indexName, newProperties) 
.then(function success(value){ 
     console.log('migration successful'); 
    }, function error(){ 
     console.log('migration unsuccessful'); 
    }); 

方法elastic.putSettings抛出错误,但由于某些原因,console日志'migration is successful'。我希望错误处理程序被调用。

如果我改变的方法是:

var tryWithoutReindexing = function(indexName, properties) { 
     var settings = properties["settings"]; 
     var mappings = properties["mappings"]; 
     return elastic.closeIndex(indexName) 
      .then(elastic.putSettings(indexName, settings)) 
       .then(function success() { 
       console.log('err'); 
      }, function(error) { 
       console.log(error); 
      }) 
      .then(elastic.putMapping(indexName, mappings)) 
      .then(elastic.openIndex(indexName)); 
}; 

,并把符合console.log(error);断点,错误处理程序被调用,因此它似乎putSettings法正常工作。

有没有人可以解释我为什么第一个例子不处理承诺链中出现的错误?

+0

它似乎并没有显示您的实际代码。你的替代版本的方法有分配'settings'和'mappings'的行,而你的第一个版本没有这个,但仍然使用这些变量。请将您的代码削减为实际产生问题的内容,但是您可以在此修改此内容。我们需要看到实际的代码,因为魔鬼在细节中。 – JLRishe

+0

@JLRishe更新,这是唯一的区别,我省略了简洁 – Raston

我假设elastic.putSettings()等人返回一个承诺。你不能使用承诺作为.then的参数;该方法预计函数参数。反过来,这些功能可以返回一个承诺。

所以,你需要用匿名函数包装你的承诺返回函数,并使用该函数作为.then的参数。像这样:

var tryWithoutReindexing = function(indexName, properties) { 
    var settings = properties["settings"]; 
    var mappings = properties["mappings"]; 

    return elastic.closeIndex(indexName) 
       .then(function() { 
        return elastic.putSettings(indexName, settings); 
       }) 
       .then(function() { 
        return elastic.putMapping(indexName, mappings); 
       }) 
       .then(function() { 
        return elastic.openIndex(indexName); 
       }); 
}; 
+0

好吧,答案是正确的,但我需要一些澄清。 elastic.putSettings(indexName,settings)是一个返回承诺的函数包装器: putSettings:function(indexName,settings){ return client.indices.putSettings({index}:indexName, body:settings }); }, 那么为什么这不起作用呢?这是一个函数的参数,而不是一个承诺(我猜) – Raston

+0

我明白我的想法。我所做的是用参数调用函数,这导致了承诺。有没有办法通过参数传递函数引用来绑定?脂肪箭头和函数包装是选项,但我正在寻找一个班轮更干净的代码 – Raston

+1

@Raston试试这个:'.then(elastic.putSettings.bind(elastic,indexName,settings))'(它确实使代码更多简洁但不一定更清洁IMO) – robertklep