2017-01-22 81 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