2014-05-03 90 views
0

我有這個承諾我簡化了代碼,但是我不能拒絕promise0。在下面的例子中,renameProfile首先讀取一個包含所有配置文件信息的文件,在讀取完畢後,它會嘗試重新命名它,這是沒有保證的。因此,例如readFile成功,但重命名文件過程失敗。但它不拒絕。拒絕承諾,什麼時候不知道父母var

我使用Promise.jsm https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm

function doit() { 
    var promise1 = renameProfile(1); 
    promise1.then(
     function() { 
      console.log('promise1 success'); 
     }, 
     function onReject(rsn) { 
      console.log('promise1 failed rsn = ' + rsn); 
     } 
    ); 
    return promise1; 
} 

function renameProfile(readFileFirst) { 
    if (readFileFirst == 1) { 
     console.log('doing read file first'); 
     var promise2 = readFile(); 
     promise2.then(
      function() { 
       console.log('promise2 success - read file success will now rename the profile'); 
       return renameProfile(0); 
      }, 
      function (rsn) { 
       console.log('promise2 failed - read file failed rsn = ' + rsn); 
       return new Error('read file failed rsn = ' + rsn); 
      } 
     ); 
     return promise2; 
    } else if (readFileFirst == 0) { 
     //always reject promise 
     console.log('doing renameProfile'); 
     return new Error('renameProfile failed');; 
    } 
} 

function readFile() { 
    let deferred = Promise.defer(); 
    deferred.resolve('successfully read file'); 
    return deferred.promise; 
} 

var promise0 = doit(); 
promise0.then(
    function() { 
     console.log('promise0 success'); 
    }, 
    function (rsn) { 
     console.log('promise0 failed rsn = ' + rsn); 
    } 
); 
+0

承諾爲您使用該庫的規範......? jQuery的承諾,還是什麼? –

+0

嘿,我更新它有這個信息。我正在使用Firefox的Promise.jsm,我也更新了例子,所以它的工作原理,如果你從Firefox中的scratchpad運行它 – Noitidart

回答

1

那麼,關於實際(重新)拋出錯誤的觀點已經作出......但這不是唯一的錯誤在這裏... doIt()將返回結果renameProfile(1),總是promise2 = readFile()總是成功。

你打算做的是返回不是promise2,而是promise2.then(...),這是另一個承諾,傳播結果或promise2回調(s)。

Promise.then() returns

最初被掛起一個新的承諾,那麼假定 依賴於調用回調函數的結果狀態:

  • 如果回調返回的值是不是承諾,包括未定義,即使原始承諾被拒絕,新承諾也會滿足此履行價值,即 。
  • 如果回調引發異常,則新承諾將被拒絕,並將異常作爲拒絕原因,即使原始承諾履行完畢。
  • 如果回調函數返回一個承諾,那麼新的承諾將最終呈現與返回的承諾相同的狀態。

因此,這裏是我怎麼想更正代碼:

function doit() { 
    var promise1 = renameProfile(1); 
    promise1.then(
     function() { 
      console.log('promise1 success'); 
     }, 
     function onReject(rsn) { 
      console.log('promise1 failed rsn = ' + rsn); 
     } 
    ); 
    return promise1; 
} 

function renameProfile(readFileFirst) { 
    if (readFileFirst == 1) { 
     console.log('doing read file first'); 
     var promise2 = readFile(); 
     // !!! return the right thing. 
     return promise2.then(
      function() { 
       console.log('promise2 success - read file success will now rename the profile'); 
       return renameProfile(0); 
      }, 
      function (rsn) { 
       console.log('promise2 failed - read file failed rsn = ' + rsn); 
       throw new Error('read file failed rsn = ' + rsn); 
      } 
     ); 
    } else if (readFileFirst == 0) { 
     //always reject promise 
     console.log('doing renameProfile'); 
     throw new Error('renameProfile failed'); 
    } 
} 

function readFile() { 
    let deferred = Promise.defer(); 
    deferred.resolve('successfully read file'); 
    return deferred.promise; 
} 

var promise0 = doit(); 
promise0.then(
    function() { 
     console.log('promise0 success'); 
    }, 
    function (rsn) { 
     console.log('promise0 failed rsn = ' + rsn); 
    } 
); 

promise1.then()只是爲了記錄和對結果沒有影響)。

從而造成

"doing read file first" Scratchpad/1:16 
"promise2 success - read file success will now rename the profile" Scratchpad/1:20 
"doing renameProfile" Scratchpad/1:30 
"promise1 failed rsn = Error: renameProfile failed" Scratchpad/1:8 
"promise0 failed rsn = Error: renameProfile failed" Scratchpad/1:47 
+0

Noooo wayyy !!我爲此奮鬥了幾天!謝啦!! – Noitidart

+0

快速問題的人,我認爲它是真實的,我測試了它,但只是爲了驗證,拋出後,它會中止運行權?所以就像'拋出新的錯誤('blah')'相當於把'reuturn Promise.reject(new Error('blah'))''? – Noitidart

5

承諾的工作就像同步碼 - 你可以隨意拋出錯誤。在你的情況下,你是返回一個Error對象,不會拋出它。

throw new Error('renameProfile num == 2'); 

應拒絕承諾並觸發錯誤處理。

+0

感謝人生病測試拋出。我正在返回新的錯誤,並沒有被拒絕。你有沒有聽說過將錯誤作爲拒絕承諾的方式? – Noitidart

+0

我更新的例子,你可以請看看,它不起作用。:( – Noitidart

+0

你仍然在你的例子中返回錯誤 – SomeKittens

相關問題