2017-01-22 94 views
2

使用ES6 Promise,如何在以下情況下將其分解?NodeJS違反Promise

addClient: function(request, response, next) { 
    var id = mongo.validateString(request.body.id); 

    mongo.Test.findOne({ 
     id: id 
    }) 
    .then(client => { 
     if (client) { 
      // want to break here 
      response.status(400).send({ 
       error: 'client already exists' 
      }); 
     } else { 
      return auth.hashPassword(mongo.validateString(request.body.secret)); 
     } 
    }) 
    .then(hashedSecret => { 
     // gets executed even if I don't return anything 
     return new mongo.Test({ 
      name: mongo.validateString(request.body.name), 
      id: id, 
      secret: hashedSecret 
     }).save(); 
    }) 
    .then(doc => { 
     return response.status(201).send({ 
      client: { 
       id: doc._id 
      } 
     }); 
    }) 
    .catch(err => { 
     return next(err); 
    }); 
} 

我還沒有找到任何明確的文檔說明如何打破這一點。 而不是鏈接then我可以在第一個then內部,但在更復雜的請求,它將是很高興能夠讓他們鏈接。

+0

我不確定這是乾淨的,規範的方式可能。看到[這個答案](https://stackoverflow.com/questions/29478751/how-to-cancel-an-emcascript6-vanilla-javascript-promise-chain)爲類似的東西。過去,我通過每個'then'返回'null'來實現這一點,這是令人恐怖的混亂;或者當我想在'catch'語句中打破並測試這個語句時拋出,這又一次讓人覺得很尷尬。 –

回答

0
// gets executed even if I don't return anything 
return new mongo.Test({ 
     name: mongo.validateString(request.body.name), 
     id: id, 
     secret: hashedSecret 
    }).save(); 

即使您不返回任何內容,也會執行此操作,因爲此類事件的默認返回值爲undefined。假設代碼undefined

解決。如果這個值是不是一個承諾,包括定義,它成爲在this

您可以將相關承諾的履約價值

Mozilla的文檔通過儘早拒絕它來打破Promise鏈。

addClient: function (request, response, next) { 
    var id = mongo.validateString(request.body.id); 
    mongo.Test.findOne({ 
    id: id 
    }).then(client => { 
    if (client) { 
     // reject with a type 
     return Promise.reject({ 
     type: 'CLIENT_EXISTS' 
     }); 
    } 
    return auth.hashPassword(mongo.validateString(request.body.secret)); 
    }).then(hashedSecret => { 
    // gets executed even if I don't return anything 
    return new mongo.Test({ 
     name: mongo.validateString(request.body.name), 
     id: id, 
     secret: hashedSecret 
    }).save(); 
    }).then(doc => { 
    return response.status(201).send({ 
     client: { 
     id: doc._id 
     } 
    }); 
    }).catch((err) => { 
    // check type 
    if (err.type === 'CLIENT_EXISTS') { 
     return response.status(400).send({ 
     error: 'client already exists' 
     }); 
    } 
    return next(err); 
    }); 
} 
0

如果你想打破諾言鏈又名不執行以下鏈接承諾鏈接,您可以通過返回永遠不會解決一個承諾注入尚未解決的承諾到鏈。

new Promise((resolve, reject) => { 
    console.log('first chain link executed') 
    resolve('daniel'); 
}).then(name => { 
    console.log('second chain link executed') 
    if (name === 'daniel') { 
     return new Promise(() => { 
      console.log('unresolved promise executed') 
     }); 
    } 
}).then(() => console.log('last chain link executed')) 




// VM492:2 first chain link executed 
// VM492:5 second chain link executed 
// VM492:8 unresolved promise executed