javascript - 链接多个 Promise(处理回调)

标签 javascript angularjs promise angular-promise

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

注册流程如下:

  • 用户选择别名 -> 详细信息别名 + userID(设备的通用唯一标识符)发送到服务器端
  • 如果别名可用,则生成 ApiKey( token ),用户注册并发回客户端(存储在数据库中)

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));


现在,在我的 Controller 中,我想链接上面的两个 promise 。我引用文档中的以下内容:

then(successCallback, errorCallback, notifyCallback) – 无论 Promise 何时被解决或被拒绝,一旦结果可用,就会异步调用成功或错误回调之一。使用单个参数调用回调:结果或拒绝原因。此外,在解决或拒绝 promise 之前,可以调用通知回调零次或多次以提供进度指示。

  1. 如果无论 Promise 是否得到解决,回调都会触发,那么回调还有什么意义?
  2. 我不应该在第一个 Promise 的成功回调中调用例如 Promise2 吗?如果无论Promise1是否被解析,它都会被触发,那么我如何才能以仅当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');
                    });
  }]);

注释:我知道在客户端存储详细信息是一种不好的做法,但是,我追求不同的概念(匿名消息传递)并且不存在安全问题。

感谢您的宝贵时间

最佳答案

您的第二个 then 调用似乎不正确,之后

//Call Promise 2 & Store details Client-Side using .then()

then 最多需要 3 个参数 then(successCallback, errorCallback, notifyCallback) 您正在传递它: deviceDB.RegDevice($scope.alias, $ scope.apiKey, $scope.Device) 立即评估,返回的 Promise 被传递给函数 then 作为 success 函数,您的 success 函数作为 errorCallback 传递,而您的 failed函数作为notifyCallback 传递。

我会尝试以下方法

 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 */}

请注意,对 RegDevice 的调用现在位于函数 block 内,并且从您想要链接的 then block 返回了一个 Promise。

关于javascript - 链接多个 Promise(处理回调),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26006736/

相关文章:

javascript - 类型安全从函数对象调用某些函数

javascript - IE 9 不显示由 js 填充的表

javascript - Angularjs ng 单击清除输入并更新范围

javascript - 如何设置带 Angular 文本阴影?

node.js - AWS Cloud9 Lambda 安装node.js 模块

javascript - 为什么这个jquery效果不起作用?

javascript - string.replace ("é", "e") 不工作

angularjs - ng-grid cellTemplate 问题与单元格的背景颜色

javascript - Node JS 从 axios 返回数据

javascript - 如何以设定的频率调用 promise ?