Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.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_Angularjs_Promise_Angular Promise - Fatal编程技术网

Javascript 链接多个承诺(处理回调)

Javascript 链接多个承诺(处理回调),javascript,angularjs,promise,angular-promise,Javascript,Angularjs,Promise,Angular Promise,当涉及到链接多个承诺时,我在承诺方面遇到了一些困难。混淆之处在于如何正确利用承诺及其与回调的区别。我注意到,无论承诺是否得到解决,回调有时会触发,这使得下面的实现不可靠。(除非我的语法和逻辑错误)我阅读了官方文档并提出了这个方法,但我不确定它是否得到了很好的实现。注册流程如下: function do_all() { var task_1 = function() {

当涉及到链接多个承诺时,我在承诺方面遇到了一些困难。混淆之处在于如何正确利用承诺及其与回调的区别。我注意到,无论承诺是否得到解决,回调有时会触发,这使得下面的实现不可靠。(
除非我的语法和逻辑错误)
我阅读了官方文档并提出了这个方法,但我不确定它是否得到了很好的实现。

注册流程如下:

function do_all() {                                                         
    var task_1 = function() {                                                  
        return $http.get("some url")                                           
            .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
    }                                                                          

    var task_2 = function(some_data) {                                         
        vm.bla = some_data;                                                    
        return $http.get("other url")                                          
            .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
    }                                                                          

    var task_3 = function(other_data) {                                        
        vm.bli = other_data;                                                   
    }                                                                       

    var tasks = [task_1, task_2, task_3];                                      

    return $q.serial(tasks)                                                    
        .then(function() {                                                     
            console.log("Finished tasks 1, 2 and 3!!!");                       
        });                                                                    
}  
  • 用户选择别名->详细信息别名+用户ID(设备的通用唯一标识符)发送到服务器端
  • 如果别名可用,则生成ApiKey(令牌),用户注册并发送回客户端(存储在DB中)
Services.js

(function(angular) {
   myApp.factory("deviceDB.Service", ['$resource', '$http', '$q',
   function ($resource,  $http , $q ) {

    return {

//Second Promsie : After API token is generated server-side, store res in db

        RegDevice: function (alias, apiKey, userID) { 
            var deferred = $q.defer();
            var configuration ;
            var db = window.sqlitePlugin.openDatabase({name: "config.db"});
            setTimeout(function () {

                db.transaction(function (tx) {
                    tx.executeSql('CREATE TABLE IF NOT EXISTS user_details (userID UNIQUE , alias TEXT, apiKey TEXT)');
                    tx.executeSql("INSERT INTO user_details (userID, alias, apiKey) VALUES (?,?,?)", [userID, alias, apiKey], function (tx, res) {

                        deferred.resolve(configuration = true);
                    }, function (e) {
                        // console.log("ERROR: " + e.message);
                        deferred.reject(configuration = false);
                    });
                });

            }, 1000);
            return deferred.promise;
        },

//First Promsie: Register user  server side & generate APi token

        RegUser: function (alias, userID) { 

            var deferred = $q.defer();
            var pro;
            pro = $resource('api/query/register', {'alias': alias, 'userID': userID},
                { query: {
                        isArray: false,
                        method: 'GET'  } });

            setTimeout(function () {
                pro.query(function (res) {
                    if (res.error) {
                        deferred.reject( { error : res.error, exists: res.exists,  msg: res.message } );
                    }
                    else {
                        deferred.resolve( {error : res.error , alias: res.alias , apiKey: res.apiKey, msg: res.message } );
                    }
                }, function (e) {
                    deferred.reject( { errorStatus: e.status } );

                });

            }, 1000);
            return deferred.promise;
        }

    };

  }]);

}(window.angular));
function do_all() {                                                         
    var task_1 = function() {                                                  
        return $http.get("some url")                                           
            .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
    }                                                                          

    var task_2 = function(some_data) {                                         
        vm.bla = some_data;                                                    
        return $http.get("other url")                                          
            .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
    }                                                                          

    var task_3 = function(other_data) {                                        
        vm.bli = other_data;                                                   
    }                                                                       

    var tasks = [task_1, task_2, task_3];                                      

    return $q.serial(tasks)                                                    
        .then(function() {                                                     
            console.log("Finished tasks 1, 2 and 3!!!");                       
        });                                                                    
}  

现在,在我的控制器中,我想链接上面的两个承诺。我引用文档中的以下内容:

function do_all() {                                                         
    var task_1 = function() {                                                  
        return $http.get("some url")                                           
            .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
    }                                                                          

    var task_2 = function(some_data) {                                         
        vm.bla = some_data;                                                    
        return $http.get("other url")                                          
            .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
    }                                                                          

    var task_3 = function(other_data) {                                        
        vm.bli = other_data;                                                   
    }                                                                       

    var tasks = [task_1, task_2, task_3];                                      

    return $q.serial(tasks)                                                    
        .then(function() {                                                     
            console.log("Finished tasks 1, 2 and 3!!!");                       
        });                                                                    
}  
then(successCallback、errorCallback、notifyCallback)
–无论承诺是在何时或将在何时解决或拒绝,只要结果可用,就异步调用其中一个成功或错误回调。调用回调时只需一个参数:结果或拒绝原因。此外,在承诺被解决或拒绝之前,notify回调可能被调用零次或多次以提供进度指示。

function do_all() {                                                         
    var task_1 = function() {                                                  
        return $http.get("some url")                                           
            .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
    }                                                                          

    var task_2 = function(some_data) {                                         
        vm.bla = some_data;                                                    
        return $http.get("other url")                                          
            .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
    }                                                                          

    var task_3 = function(other_data) {                                        
        vm.bli = other_data;                                                   
    }                                                                       

    var tasks = [task_1, task_2, task_3];                                      

    return $q.serial(tasks)                                                    
        .then(function() {                                                     
            console.log("Finished tasks 1, 2 and 3!!!");                       
        });                                                                    
}  
  • 如果无论承诺是否得到解决,他们都可以解雇,那么进行回调又有什么意义呢
  • 我不应该在第一次承诺成功的回访中要求承诺吗?如果无论Promise1是否已解决,都会触发Promise2,那么我如何才能以仅当Promise1已解决时才触发的方式来连锁Promise2

  • 我尝试的:
    Controller.js

    myApp.controller('RegisterController', ['$scope', '$http', 'deviceDB.Service',
        function ($scope , $http , deviceDB.Service) {
    
       var Promise1 = deviceDB.RegUser($scope.alias, $scope.Device); 
    
    // First promise - Validate with server
       Promise1.then(function(data)
                        {
                            console.log(' Registration Server-Side successfully');
                            $scope.apiKey = data.apiKey;
                            term.echo(data.apiKey);
    
                        }, function(e)
                        {
                            console.log('Registration Failed');
                            term.echo(e.msg);
    
                        })
    
    //Call Promise 2 & Store details Client-Side using .then()
    
        .then(deviceDB.RegDevice($scope.alias, $scope.apiKey, $scope.Device), 
         function(d){
                           console.log('Items Stored in DB successfully');
                        }, function()
                        {
                            console.log('Items Stored in DB Failed');
                        });
      }]);
    
    function do_all() {                                                         
        var task_1 = function() {                                                  
            return $http.get("some url")                                           
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_2 = function(some_data) {                                         
            vm.bla = some_data;                                                    
            return $http.get("other url")                                          
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_3 = function(other_data) {                                        
            vm.bli = other_data;                                                   
        }                                                                       
    
        var tasks = [task_1, task_2, task_3];                                      
    
        return $q.serial(tasks)                                                    
            .then(function() {                                                     
                console.log("Finished tasks 1, 2 and 3!!!");                       
            });                                                                    
    }  
    
    注意:我理解在客户端存储详细信息是一种不好的做法,但是,我追求的是一种不同的概念(匿名消息),并且没有安全问题。

    function do_all() {                                                         
        var task_1 = function() {                                                  
            return $http.get("some url")                                           
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_2 = function(some_data) {                                         
            vm.bla = some_data;                                                    
            return $http.get("other url")                                          
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_3 = function(other_data) {                                        
            vm.bli = other_data;                                                   
        }                                                                       
    
        var tasks = [task_1, task_2, task_3];                                      
    
        return $q.serial(tasks)                                                    
            .then(function() {                                                     
                console.log("Finished tasks 1, 2 and 3!!!");                       
            });                                                                    
    }  
    

    感谢您抽出时间

    您的第二个then电话似乎不正确

    //Call Promise 2 & Store details Client-Side using .then()
    
    function do_all() {                                                         
        var task_1 = function() {                                                  
            return $http.get("some url")                                           
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_2 = function(some_data) {                                         
            vm.bla = some_data;                                                    
            return $http.get("other url")                                          
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_3 = function(other_data) {                                        
            vm.bli = other_data;                                                   
        }                                                                       
    
        var tasks = [task_1, task_2, task_3];                                      
    
        return $q.serial(tasks)                                                    
            .then(function() {                                                     
                console.log("Finished tasks 1, 2 and 3!!!");                       
            });                                                                    
    }  
    
    then
    最多使用3个参数
    then(successCallback、errorCallback、notifyCallback)
    您正在传递它:
    deviceDB.RegDevice($scope.alias、$scope.apiKey、$scope.Device)
    它会立即进行计算,返回的承诺会作为success函数传递给函数
    then
    ,成功函数作为errorCallback传递,失败函数作为notifyCallback传递

    function do_all() {                                                         
        var task_1 = function() {                                                  
            return $http.get("some url")                                           
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_2 = function(some_data) {                                         
            vm.bla = some_data;                                                    
            return $http.get("other url")                                          
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_3 = function(other_data) {                                        
            vm.bli = other_data;                                                   
        }                                                                       
    
        var tasks = [task_1, task_2, task_3];                                      
    
        return $q.serial(tasks)                                                    
            .then(function() {                                                     
                console.log("Finished tasks 1, 2 and 3!!!");                       
            });                                                                    
    }  
    
    我想试试下面的方法

     Promise1.then(function(data)
     {
       console.log(' Registration Server-Side successfully');
       $scope.apiKey = data.apiKey;
       term.echo(data.apiKey);
    
       return deviceDB.RegDevice($scope.alias, $scope.apiKey, $scope.Device)
    
     }, function(e)
     {
       console.log('Registration Failed');
       term.echo(e.msg);
    
       return e;
    
     }).then(function(d) {/*all good*/}, function(e) {/* all bad */}
    
    function do_all() {                                                         
        var task_1 = function() {                                                  
            return $http.get("some url")                                           
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_2 = function(some_data) {                                         
            vm.bla = some_data;                                                    
            return $http.get("other url")                                          
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_3 = function(other_data) {                                        
            vm.bli = other_data;                                                   
        }                                                                       
    
        var tasks = [task_1, task_2, task_3];                                      
    
        return $q.serial(tasks)                                                    
            .then(function() {                                                     
                console.log("Finished tasks 1, 2 and 3!!!");                       
            });                                                                    
    }  
    
    请注意,对RegDevice的调用现在位于一个函数块中,并且从要链接的then块返回一个承诺

    我发现了一个很好的链接承诺的库。它非常容易使用,可以处理很多事情,比如检查链上的所有承诺是否都是真正的承诺

    function do_all() {                                                         
        var task_1 = function() {                                                  
            return $http.get("some url")                                           
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_2 = function(some_data) {                                         
            vm.bla = some_data;                                                    
            return $http.get("other url")                                          
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_3 = function(other_data) {                                        
            vm.bli = other_data;                                                   
        }                                                                       
    
        var tasks = [task_1, task_2, task_3];                                      
    
        return $q.serial(tasks)                                                    
            .then(function() {                                                     
                console.log("Finished tasks 1, 2 and 3!!!");                       
            });                                                                    
    }  
    
    下面是一个小例子:

    function do_all() {                                                         
        var task_1 = function() {                                                  
            return $http.get("some url")                                           
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_2 = function(some_data) {                                         
            vm.bla = some_data;                                                    
            return $http.get("other url")                                          
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_3 = function(other_data) {                                        
            vm.bli = other_data;                                                   
        }                                                                       
    
        var tasks = [task_1, task_2, task_3];                                      
    
        return $q.serial(tasks)                                                    
            .then(function() {                                                     
                console.log("Finished tasks 1, 2 and 3!!!");                       
            });                                                                    
    }  
    

    以下是一种使用async/await可能会有所帮助的方法:

    function do_all() {                                                         
        var task_1 = function() {                                                  
            return $http.get("some url")                                           
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_2 = function(some_data) {                                         
            vm.bla = some_data;                                                    
            return $http.get("other url")                                          
                .then(on_xhr_completed_fn, on_xhr_failed_fn);                      
        }                                                                          
    
        var task_3 = function(other_data) {                                        
            vm.bli = other_data;                                                   
        }                                                                       
    
        var tasks = [task_1, task_2, task_3];                                      
    
        return $q.serial(tasks)                                                    
            .then(function() {                                                     
                console.log("Finished tasks 1, 2 and 3!!!");                       
            });                                                                    
    }  
    
    async function run_promise_A(args) {
        return new Promise((resolve, reject) => {
            return resolve(resolve_value)
        });
    }
    
    async function run_promise_B(args) {
        return new Promise((resolve, reject) => {
            return resolve(resolve_value)
        });
    }
    
    async function run_promise_C(args) {
        return new Promise((resolve, reject) => {
            return resolve(resolve_value)
        });
    }
    
    async function run_several_async_functions(userid) {
        let a = run_promise_A(userid);
        let b = run_promise_B(a);
        let c = run_promise_C(b);
        return c;
    }
    
    return Promise.resolve()
        .then(() => {
            let c = (async () => {
                let c = await run_several_async_functions(userid)
                return c;
            })();
            return c;
        })
        .then((c) => {
            return c;
        })
        .catch((err) => {
            console.log(err);
        });
    

    因此,如果我理解正确,这里Promise1接受3个参数,返回的promise RegDevice在成功回调中(放置在第一个Arumgin中)。它工作正常,事件同步触发,首先Promise1,然后2。第二个then()[函数(d)success/函数(e)error是promise2的回调吗?因此,如果我有3个承诺,我会从函数(d)return中调用第三个,以此类推