2016-08-19 112 views
0

在node.js环境中使用Bluebird promise,我检查是否存在文件的三种可能变体中的任何一种或不存在(image.png/image.gif/image .jpg)在我的服务器上。如果这三个文件中有一个存在,它应该返回给用户。如果三个文件都不存在,则应返回默认图像。到目前为止,我想出了这个代码:Node.js Bluebird Promise:promise.any返回默认图像

var promise1 = new Promise(function(resolve, reject) { 
    fs.statAsync('./image.jpg') 
    .then(function(result) { 
     if(result){ 
      resolve('jpg'); 
     } 
    }).catch(function(err){ 
     //foo 
    });  
}); 

var promise2 = new Promise(function(resolve, reject) { 
    fs.statAsync('./image.gif') 
    .then(function(result) { 
     if(result){ 
      resolve('gif'); 
     } 
    }) 
    .catch(function(err){ 
     //foo 
    });  
}); 

var promise3 = new Promise(function(resolve, reject) { 
    fs.statAsync('./image.png') 
    .then(function(result) { 
     if(result){ 
      resolve('png'); 
     } 
    }) 
    .catch(function(err){ 
     //foo 
    });  
}); 

Promise.any([ 
    promise1, 
    promise2, 
    promise3 
]).then(function(result) { 
    res.sendfile("./image."+result); 
}).catch(function(err){ 
    res.sendfile("./default.png"); 
}); 

问题是:只要这三个文件中的一个存在,一切都运行得很好。但是我不能让它工作,以便在没有找到三个文件的情况下返回默认图像。

+1

如果找不到图像,您需要在每个承诺中使用'reject' –

+0

这是一种反模式,可以在使用'fs.statAsync()'已经返回的内容时创建这些新承诺。您可以在'.then()'处理程序中评估结果并根据需要更改已解析的状态。无需将这些包装在自己的新承诺中。事实上,你的一些错误是由于这个承诺包装,这是不必要的,容易出错。 – jfriend00

回答

1

statAsync已经返回Promise,所以你不需要自己创建(这样做是an antipattern)。如果你简单地映射解决Stats值到你想要的值,你就不必担心resolvereject调用等

var promise1 = fs.statAsync('./image.jpg') 
    .then(function() { return 'jpg'; }); 

var promise2 = fs.statAsync('./image.gif') 
    .then(function() { return 'gif'; }); 

var promise3 = fs.statAsync('./image.png') 
    .then(function() { return 'png'); }); 

Promise.any([ 
    promise1, 
    promise2, 
    promise3 
]).then(function(result) { 
    res.sendfile("./image."+result); 
}).catch(function(err){ 
    res.sendfile("./default.png"); 
}); 

如对发布你的问题的评论中提到,你的代码是不是因为当statAsync失败时,您不会拒绝您创建的Promise,但您不应首先创建自己的Promise

+0

对不起,反模式。我应该更清楚。只是有时候我仍然在努力应对承诺的概念和解决/拒绝事件的传递。事实上,为什么上面的代码工作?我的意思是,没有拒绝或抛出指令。为什么赶上进攻?! : -/ –

+0

SO答案 - 更不用说评论了 - 并不是解释承诺如何工作的最佳地点。然而,上面的代码是可行的,因为'statAsync'实现可以解决或拒绝承诺,'Promise.any'实现连接'then'和'catch'调用。如果数组中的所有promise均被拒绝,则将调用链接到Promise.any的catch。如果数组中的单个promise被解析,那么链接到'Promise.any'的'then'将被调用。在其他地方找到介绍性/解释性信息应该没有问题。 – cartant