2016-09-28 102 views
1

我想了解node.js中的承諾。這裏是一個示例代碼理解node.js中的承諾拒絕

con.queryReturnPromise("SELECT * FROM bookings WHERE driverId = " + accId + " AND bookingStatus = " + config.get('BOOKING_STATUS_ACTIVE') + " LIMIT 1") 
    .catch((err) => { 

    callback({ 
     "message": "Success", 
     "error": true, 
    }); 
    console.log("mysql query error"); 
    return Promise.reject(); 
    }) 
    .spread((rows, fields) => { 
    if (rows.length != 1) { 
     return Promise.reject(); 
    } 
    mBooking = rows[0]; 
    var query = "INSERT INTO locations SET timeStamp = " + timeStamp + " latitude = " + lat + ", longitude = " + lng + ", bookingId = " + mBooking.id; 
    return con.queryReturnPromise(query) 
    }) 
    .catch((err) => { 
    if (err) 
     console.log("Adding Location error" + err); 
    return Promise.reject(); 
    }) 
    .spread(() => { 
    return funcs.getBooking(con, mBooking.id) 
    }) 
    .then((booking) => { 
    if (mBooking.userId.toString() in userSockets) { 
     userSockets[mBooking.userId].emit(config.get('EVENT_USER_UPDATE_BOOKING'), { 
     "message": "Success", 
     "error": false, 
     "booking": booking 
     }); 
     userId = mBooking.userId.toString(); 
    } 
    callback({ 
     "message": "Success", 
     "error": false, 
     "booking": booking 
    }); 
    }) 
    .catch((err) => { 
    if (err) 
     console.log(err); 
    }); 

該代碼非常簡單。然而我有一個困惑。如果調用了return Promise.reject(),函數會在哪裏調用哪個代碼。例如,如果第一個catch子句被調用,它調用返回Promise.reject()其中下面的代碼部分將隨後運行

承諾在for循環

data = JSON.parse(data); 
      var promisesArray = []; 
      for (var i = 0; i < data.length; i++) 
      { 
       var location = data[i]; 
       var lng  = location.lng; 
       var lat  = location.lat; 
       var bearing = location.bearing; 
       var deltaTime = location.deltaTime; 
       var timeStamp = location.timeStamp; 

       var query = "INSERT INTO locations SET timeStamp = " + timeStamp + " latitude = " + lat + ", longitude = " + lng + ", bookingId = " + mBooking.id; 


       var promise = con.queryReturnPromise(query)      
         .then(() => {        
         }); 

       promisesArray[] = promise; 
      } 

      Promise.all(promisesArray) 
      .then(function(results) 
      { 
        callback({ 
         "error": false, 
        });    
      }); 
+1

糾正我,如果我錯了,但應該只有一個'趕上()'鏈中的方法調用。如果你想在每一步之後支持捕獲錯誤,那麼你應該在'then()'方法中提供錯誤回調作爲第二個參數。 – sunpietro

+0

注意:使用'.spread()'時,不要使用'.then(([rows,fields])=> {...})'而不是使用ES2015語法。 –

+0

@MadaraUchiha爲什麼不鼓勵?性能? – thefourtheye

回答

5

每次做return Promise.reject()時間,接下來.catch()處理程序在那個鏈中將會被調用。它將跳過任何.then()處理程序,直到下一個.catch()處理程序。

.then()處理程序或.catch()處理程序返回拒絕承諾會導致拒絕當前承諾鏈。所以,當遇到更多的處理程序時,鏈中的下一個拒絕處理程序將被調用。

當你點擊一個.catch()處理程序,這是什麼.catch()後會發生取決於什麼呢.catch()。如果它拋出或返回一個被拒絕的承諾,那麼承諾停留在拒絕狀態,鏈中的下一個.catch()將執行。如果它沒有返回任何東西或任何常規值(除了最終拒絕的承諾之外),那麼承諾就會解決(不再被拒絕),然後鏈中的下一個處理器運行。

下面是一個例子:

a().then(function() { 
    // makes promise chain assume rejected state 
    return Promise.reject(); 
}).then(function() { 
    // this will not get called because promise is in rejected state 
}).catch(function() { 
    // this will get called 
    // returning a reject promise will keep the promise in the reject state 
    return Promise.reject(); 
}).then(function() { 
    // this will not get called because promise is in rejected state 
}).catch(function() { 
    // this will get called 
    return 2; 
}).then(function(val) { 
    // this will get called because prior `.catch()` "handled" the rejection 
    // already 
    console.log(val); // logs 2 
}).catch(function() { 
    // this is not called because promise is in resolved state 
}); 
+0

所以如果我在第一個catch子句中得到拒絕,那麼系統地將所有catch子句放在我的代碼中運行? –

+2

@MuhammadUmar - 編號只有下一個'.catch()'運行,.catch()後面會發生什麼,取決於'.catch()'返回或拋出的內容。拒絕承諾或拋出異常,則下一個'.catch()'將運行,如果它沒有返回任何值或正常值,則承諾將被解析並且下一個'.then()'處理程序將運行 – jfriend00

+0

我的代碼下一個捕獲有錯誤,然後再次返回拒絕。所以控制檯會記錄一個錯誤,並將切換到下一個捕獲 –