Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 承诺基础。如何推荐异步节点代码?_Javascript_Node.js_Asynchronous_Promise_Q - Fatal编程技术网

Javascript 承诺基础。如何推荐异步节点代码?

Javascript 承诺基础。如何推荐异步节点代码?,javascript,node.js,asynchronous,promise,q,Javascript,Node.js,Asynchronous,Promise,Q,我从承诺开始,并尝试使用它们而不是回调来避免回调地狱。异步函数是来自MongoDB、Redis、bcrypt模块等的函数的混合体。我能够做到这一点: var insert = Q.denodify(db.collection(USERS).insert); var createCollection = Q.denodify(db.createCollection); var sadd = Q.denodify(redisClient.sadd); var sismember = Q.denodi

我从承诺开始,并尝试使用它们而不是回调来避免回调地狱。异步函数是来自MongoDB、Redis、bcrypt模块等的函数的混合体。我能够做到这一点:

var insert = Q.denodify(db.collection(USERS).insert);
var createCollection = Q.denodify(db.createCollection);
var sadd = Q.denodify(redisClient.sadd);
var sismember = Q.denodify(redisClient.sismember);
var genSalt = Q.denodify(bcrypt.genSalt);
var hash = Q.denodify(bcrypt.hash);

// SANITY CHECK
// a "name" parameter is required
if(!req.body.name || !isValidName(req.body.name)) 
    return next(get400InvalidNameError());

// SANITY CHECK
// a "key" is optional
// if one is supplied, it must be valid
// this key will be hashed later
if(req.body.key){
    if(!isValidKey(req.body.key))
        return next(get400InvalidKeyError());
}

// STEPS:
// 1. 
// check Redis cache to see if the "name" is already taken
// if yes, return error. if no, continue
// 2. 
// construct a "user" object with name = req.body.name
// 3. 
// req.body.key provided?
// if yes, generate salt and hash the key. Set user.key = hash
// if not, continue
// 4.
// create a collection in MongoDB with the same name as req.body.name
// 5.
// add req.body.name to cache
// 6. 
// send a response to user using res.json() / res.end()
sismember(USERS,req.body.name)
.then(createUserObj,errHandler)
.then(genSalt(10),errHandler)
.then(hash(req.body.key,salt))
.then(createCollection(req.body.name),errHandler)
.then(sadd(USERS,req.body.name),errHandler)
.then(insert(user),errHandler)
.then(get200UserCreated,errHandler)
让我困惑的是最后一部分,所有这些函数都是
then()
-ed在一起的。我有几个问题:
1.如何将一个异步函数的结果提供给另一个?
2.如何有条件地决定执行哪些函数?例如,我只想在提供了
req.body.key
时生成salt和hash 3.我的
then()
顺序正确吗

  • 如何将一个异步函数的结果提供给另一个异步函数
  • 当你使用承诺时,你可以解决或拒绝它

    var myprom = Promise.resolve(1) // the simplest promise way
    
    这里,如果我们用
    链接,那么
    参数将等于1

    myprom.then(function( val ){
        
        console.log(val); // 1
        return 33;
    
    }).then(function(passed){
        
        console.log(passed) // 33
        return 44;
    
    }).then(function(other){
        
        console.log(other) // 44
        if( other > 44 ){
            return 'AAA';
        } else {
            return 'BBB';
        }
    }).then(function(res){
        
        console.log(res) // BBB
        
    })
    
    这里的重要的是你从你的承诺中得到回报。
    现在是异步。第部分:

    // we can also instanciate a new Promise object
    var myprom = new Promise(function(resolve , reject){
       
       console.log('we start here');
       
       setTimeout(function(){
           console.log('we continue here');
           resolve( 'time out' );
       } , 2000);
    
    }).then(function( val ){ 
        console.log('and we end here : ' + val);
    });
    
    第二部分
    ,然后在第一部分中调用
    resolve

    所以我们总是等到最后,这是承诺的“魔力”

    传递给resolve的参数将成为下一个
    的参数,然后

    这与我们关于
    返回的第一个示例相同
    它非常重要

    当您这样做时:

     sismember(USERS,req.body.name)
    
    这与超时的原理相同

     var sismember = function(USERS , req.body.name){
         var promiseToReturn = new Promise(function(resolve,reject){
             var result = ''; // <---do something with USERS and req.body.name
             
             // and if it is ok 
               if(result){
                resolve( result )
               } else {// if it is not ok 
                reject( result )
               }
    
         });
         return promiseToReturn; // <-- we can chain with then
     })
     .then(createUserObj,errHandler) 
    
  • 如何有条件地决定执行哪些函数?例如,我只想在提供req.body.key时生成salt和hash
  • 不同的方法

  • 我的then()序列正确吗
  • 你不能像那样调用函数

    .then(genSalt(10),errHandler) // <-- you are invoking the result not the function
    // you are doing something like that:
    .then('Adekj34LLKDF' , errHandler)
    
    但是promise-chain提供了prev函数中的参数,您不必提供它
    见上面的例子


    解决此问题后,在末尾添加一个catch来处理可能发生的任何错误。 本部分:

    .then(get200UserCreated,errHandler)//<--- errHandler for prev then
    
    .then(insert(user),errHandler)
    
    如果在
    insert(user)
    过程中发生错误,将由下一个错误处理程序或catch处理

    sismember(USERS,req.body.name)
    .then(createUserObj,errHandler)// <-- errHandler for : sismember
    .then(genSalt(10),errHandler)// <-- errHandler for : createUserObj
    .then(hash(req.body.key,salt))// <-- missing errHandler for : genSalt
    .then(createCollection(req.body.name),errHandler)// <-- errHandler for : hash
    .then(sadd(USERS,req.body.name),errHandler)// <-- errHandler for createCollection
    .then(insert(user),errHandler)// <-- errHandler for : 
    .then(get200UserCreated,errHandler)// <-- errHandler for : insert
    .catch(errHandler)// <-- errHandler for : get200UserCreated 
    
    sismember(用户,请求主体名称)
    .然后(createUserObj,errHandler)//
    
  • 如何将一个异步函数的结果提供给另一个异步函数
  • 当你使用承诺时,你可以解决或拒绝它

    var myprom = Promise.resolve(1) // the simplest promise way
    
    这里,如果我们用
    链接,那么
    参数将等于1

    myprom.then(function( val ){
        
        console.log(val); // 1
        return 33;
    
    }).then(function(passed){
        
        console.log(passed) // 33
        return 44;
    
    }).then(function(other){
        
        console.log(other) // 44
        if( other > 44 ){
            return 'AAA';
        } else {
            return 'BBB';
        }
    }).then(function(res){
        
        console.log(res) // BBB
        
    })
    
    这里的重要的是你从你的承诺中得到回报。
    现在是异步。第部分:

    // we can also instanciate a new Promise object
    var myprom = new Promise(function(resolve , reject){
       
       console.log('we start here');
       
       setTimeout(function(){
           console.log('we continue here');
           resolve( 'time out' );
       } , 2000);
    
    }).then(function( val ){ 
        console.log('and we end here : ' + val);
    });
    
    第二部分
    ,然后在第一部分中调用
    resolve

    所以我们总是等到最后,这是承诺的“魔力”

    传递给resolve的参数将成为下一个
    的参数,然后

    这与我们关于
    返回的第一个示例相同
    它非常重要

    当您这样做时:

     sismember(USERS,req.body.name)
    
    这与超时的原理相同

     var sismember = function(USERS , req.body.name){
         var promiseToReturn = new Promise(function(resolve,reject){
             var result = ''; // <---do something with USERS and req.body.name
             
             // and if it is ok 
               if(result){
                resolve( result )
               } else {// if it is not ok 
                reject( result )
               }
    
         });
         return promiseToReturn; // <-- we can chain with then
     })
     .then(createUserObj,errHandler) 
    
  • 如何有条件地决定执行哪些函数?例如,我只想在提供req.body.key时生成salt和hash
  • 不同的方法

  • 我的then()序列正确吗
  • 你不能像那样调用函数

    .then(genSalt(10),errHandler) // <-- you are invoking the result not the function
    // you are doing something like that:
    .then('Adekj34LLKDF' , errHandler)
    
    但是promise-chain提供了prev函数中的参数,您不必提供它
    见上面的例子


    解决此问题后,在末尾添加一个catch来处理可能发生的任何错误。 本部分:

    .then(get200UserCreated,errHandler)//<--- errHandler for prev then
    
    .then(insert(user),errHandler)
    
    如果在
    insert(user)
    过程中发生错误,将由下一个错误处理程序或catch处理

    sismember(USERS,req.body.name)
    .then(createUserObj,errHandler)// <-- errHandler for : sismember
    .then(genSalt(10),errHandler)// <-- errHandler for : createUserObj
    .then(hash(req.body.key,salt))// <-- missing errHandler for : genSalt
    .then(createCollection(req.body.name),errHandler)// <-- errHandler for : hash
    .then(sadd(USERS,req.body.name),errHandler)// <-- errHandler for createCollection
    .then(insert(user),errHandler)// <-- errHandler for : 
    .then(get200UserCreated,errHandler)// <-- errHandler for : insert
    .catch(errHandler)// <-- errHandler for : get200UserCreated 
    
    sismember(用户,请求主体名称)
    .然后(createUserObj,errHandler)//
    
  • 如何将一个异步函数的结果提供给另一个异步函数
  • 当你使用承诺时,你可以解决或拒绝它

    var myprom = Promise.resolve(1) // the simplest promise way
    
    这里,如果我们用
    链接,那么
    参数将等于1

    myprom.then(function( val ){
        
        console.log(val); // 1
        return 33;
    
    }).then(function(passed){
        
        console.log(passed) // 33
        return 44;
    
    }).then(function(other){
        
        console.log(other) // 44
        if( other > 44 ){
            return 'AAA';
        } else {
            return 'BBB';
        }
    }).then(function(res){
        
        console.log(res) // BBB
        
    })
    
    这里的重要的是你从你的承诺中得到回报。
    现在是异步。第部分:

    // we can also instanciate a new Promise object
    var myprom = new Promise(function(resolve , reject){
       
       console.log('we start here');
       
       setTimeout(function(){
           console.log('we continue here');
           resolve( 'time out' );
       } , 2000);
    
    }).then(function( val ){ 
        console.log('and we end here : ' + val);
    });
    
    第二部分
    ,然后在第一部分中调用
    resolve

    所以我们总是等到最后,这是承诺的“魔力”

    传递给resolve的参数将成为下一个
    的参数,然后

    这与我们关于
    返回的第一个示例相同
    它非常重要

    当您这样做时:

     sismember(USERS,req.body.name)
    
    这与超时的原理相同

     var sismember = function(USERS , req.body.name){
         var promiseToReturn = new Promise(function(resolve,reject){
             var result = ''; // <---do something with USERS and req.body.name
             
             // and if it is ok 
               if(result){
                resolve( result )
               } else {// if it is not ok 
                reject( result )
               }
    
         });
         return promiseToReturn; // <-- we can chain with then
     })
     .then(createUserObj,errHandler) 
    
  • 如何有条件地决定执行哪些函数?例如,我只想在提供req.body.key时生成salt和hash
  • 不同的方法

  • 我的then()序列正确吗
  • 你不能像那样调用函数

    .then(genSalt(10),errHandler) // <-- you are invoking the result not the function
    // you are doing something like that:
    .then('Adekj34LLKDF' , errHandler)
    
    但是promise-chain提供了prev函数中的参数,您不必提供它
    见上面的例子


    解决此问题后,在末尾添加一个catch来处理可能发生的任何错误。 本部分:

    .then(get200UserCreated,errHandler)//<--- errHandler for prev then
    
    .then(insert(user),errHandler)
    
    如果在
    insert(user)
    过程中发生错误,将由下一个错误处理程序或catch处理

    sismember(USERS,req.body.name)
    .then(createUserObj,errHandler)// <-- errHandler for : sismember
    .then(genSalt(10),errHandler)// <-- errHandler for : createUserObj
    .then(hash(req.body.key,salt))// <-- missing errHandler for : genSalt
    .then(createCollection(req.body.name),errHandler)// <-- errHandler for : hash
    .then(sadd(USERS,req.body.name),errHandler)// <-- errHandler for createCollection
    .then(insert(user),errHandler)// <-- errHandler for : 
    .then(get200UserCreated,errHandler)// <-- errHandler for : insert
    .catch(errHandler)// <-- errHandler for : get200UserCreated 
    
    sismember(用户,请求主体名称)
    .然后(createUserObj,errHandler)//
    
  • 如何将一个异步函数的结果提供给另一个异步函数
  • 当你使用承诺时,你可以解决或拒绝它

    var myprom = Promise.resolve(1) // the simplest promise way
    
    这里,如果我们用
    链接,那么
    参数将等于1

    myprom.then(function( val ){
        
        console.log(val); // 1
        return 33;
    
    }).then(function(passed){
        
        console.log(passed) // 33
        return 44;
    
    }).then(function(other){
        
        console.log(other) // 44
        if( other > 44 ){
            return 'AAA';
        } else {
            return 'BBB';
        }
    }).then(function(res){
        
        console.log(res) // BBB
        
    })
    
    这里的重要的是你从你的承诺中得到回报。
    现在是异步。第部分:

    // we can also instanciate a new Promise object
    var myprom = new Promise(function(resolve , reject){
       
       console.log('we start here');
       
       setTimeout(function(){
           console.log('we continue here');
           resolve( 'time out' );
       } , 2000);
    
    }).then(function( val ){ 
        console.log('and we end here : ' + val);
    });
    
    第二部分
    ,然后在第一部分中调用
    resolve

    所以我们总是等到最后,这是承诺的“魔力”

    传递给resolve的参数将成为下一个
    的参数,然后