2016-11-30 86 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);