2015-03-08 32 views
1

我有以下代碼。當f2不會報錯時它工作正常。藍鳥的未處理排斥

如果有錯誤,它會生成一個Unhandled rejection Error

重寫代碼以避免Unhandled rejection Error並正確傳播到catchf1的正確方法是什麼?

let Bluebird = require('bluebird'), 
    mkdirp = Bluebird.promisify(require('mkdirp')), 
    request = Bluebird.promisify(require('request')), 
    writeFile = Bluebird.promisify(require('fs').writeFile); 

function f1() { 
    ......... 
    f2(path, fileName, options).then(.....).catch(....); 
} 

function f2(path, fileName, options) { 
    p = mkdirp(path).then(request(options).then(res => { 
     if (res[0].statusCode === 200) { 
      writeFile(fileName, res[0].body); 
      return res[0].body; 
     } else { 
      throw new Error(res[0].statusCode + ': ' + res[0].body); 
     } 
    })); 
    return p; 
} 
+0

在'f2',你是爲'p'分配一個值。什麼是'p',如果它不返回任何東西,你如何調用'.then()'返回值'f2'? – JLRishe 2015-03-08 19:48:11

+0

@JLRishe對不起,我介紹了一個修正代碼的錯誤。現在修好。 – krl 2015-03-08 19:50:28

+1

值得一提的是,在幾周內即將發佈的藍鳥3.0版本中,您將會收到警告 – 2015-03-08 21:23:13

回答

2

的問題是要傳遞一個承諾到.then()f2.then()會忽略任何不是函數的東西,所以f2真的返回是mkdirp(this.path)的承諾,這是一個很大的錯誤,原因有幾個。如果在request(options)then處理程序中引發錯誤,那麼將無法處理它。

此外,您沒有做任何事情來處理從writeFile可能的錯誤。如果您致電writeFile,則需要返回包含該承諾鏈的承諾鏈,或者在f2之內添加邏輯來處理它。

因爲它看起來像您可以在這裏並行運行mkdirp()request(),但你不使用的mkdirp()的結果,我會說這是要走的路:

function f2(path, fileName, options) { 
    var p = mkdirp(path).return(request(options)).then(res => { 
     if (res[0].statusCode === 200) { 
      return writeFile(fileName, res[0].body) 
      .return(res[0].body); 
     } else { 
      throw new Error(res[0].statusCode + ': ' + res[0].body); 
     } 
    }); 
    return p; 
} 
+0

我遇到的錯誤是由於'拋出新的錯誤(res [0] .statusCode +':'+ res [0] .body);',而不是'writeFile'。只有在執行'f2'中的'else'分支時,我纔有錯誤。 – krl 2015-03-08 20:04:42

+1

@kyrylkov是的,我的修改應該考慮到這兩個。你試過了嗎? – JLRishe 2015-03-08 20:05:22

+0

是的,我有。當拋出新的錯誤(res [0] .statusCode +':'+ res [0] .body);'被執行時,它仍然顯示出來。 – krl 2015-03-08 20:10:30