2016-11-30 84 views
1

我有以下代码将文件上传到Google云,然后获取公共URL。但是,当链接承诺时,它很快变得混乱。使用ES6类时的链接承诺

任何人都可以在我的例子中帮助一个更清晰的方式链接承诺的具体例子?

let routes = function(imageUploader) { 
    router.post('/upload', 
     imageUploader.getMulter().single('image'), 
     (req, res) => { 
      imageUploader.uploadFilePromise(req.file.path) 
       .then((filename, error) => { 
        if(error) throw new Error(error); 
        imageUploader.getExternalUrl(filename) 
         .then((publicUrl, error) => { 
          if(error) throw new Error(error); 
          console.log(publicUrl); 
         }) 

       }) 
    }); 

    return router; 
}; 

我包括我的ImageUploader类在这里以及只是一个供参考。任何其他最佳实践建议也非常受欢迎。

const Multer = require('multer'), gcloudStorage = require('./vendors/gcloud'); 

class ImageUploader { 

    constructor() { 
     this.bucket = gcloudStorage; 
    } 

    uploadFile(req, res, next) { 
     if(!req.file) { 
      next(); 
     } 

     this.bucket.upload(req.file.path, (err, file) => { 
      if(err) throw new Error(err); 
      req.file.publicUrl = this.getExternalUrl(req.file.name) 
     }) 
    } 

    uploadFilePromise(path) { 
     return new Promise((resolve, reject) => { 
      this.bucket.upload(path, (err, file) => { 
       if(err) reject(err); 
       resolve(file.name); 
      }) 
     }) 
    } 

    getExternalUrl(filename) { 
     return new Promise((resolve, reject) => { 
      this.bucket.file(filename).getSignedUrl({ 
       action: 'read', 
       expires: '03-17-2025' 
      }, (err, url) => { 
       if (err) reject(err); 
       resolve(url); 
      }); 
     }); 
    } 

    storage() { 
     return Multer.diskStorage({ 
      destination: function (req, file, cb) { 
       cb(null, 'uploads/') 
      }, 
      filename: function (req, file, cb) { 
       cb(null, Date.now() + file.originalname) 
      } 
     }); 
    } 

    getMulter() { 
     return require('multer')({ storage: this.storage() }); 
    } 
} 

module.exports = ImageUploader; 
+0

不知道什么是真正的ES6-具体谈谈这个问题吗?是的,你显示了一个'class'定义,但我不确定这个问题与使用ES6语法声明的对象或创建对象的较早ES5方式有什么不同。 – jfriend00

回答

4

传递给then()的回调只接收一个参数,而不是两个参数。

它可以(应该)返回一个值或另一个承诺,以允许进一步的链接。

如果回调之一抛出,或返回被拒绝的承诺,你可以在链的末端处理与一个捕获错误:

imageUploader.uploadFilePromise(req.file.path) 
    .then(filename => imageUploader.getExternalUrl(filename)) 
    .then(publicUrl => console.log(publicUrl)) 
    .catch(error -> console.log(error)); 
0

只是关于链接承诺与.then,我觉得它更干净,不添加缩进。

ex。

promise 
.then(do something) 
.then(do something else);