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 - Fatal编程技术网

Javascript 在连续两次角度服务呼叫期间,如何中止/取消第一次呼叫的承诺?

Javascript 在连续两次角度服务呼叫期间,如何中止/取消第一次呼叫的承诺?,javascript,angularjs,Javascript,Angularjs,当通过下拉项选择上的$http angular service进行两次连续服务调用时,假设第一次调用花费时间返回,第二次调用在第一次调用解析之前返回,则显示第二次项目选择的第一次调用的数据 所以,若在第一次调用解决之前再次进行服务调用,是否有任何方法中止第一次承诺 为了演示的目的,我创建了一个带有几个项目的下拉列表,我添加了明确的条件,在选择第一个项目时,它比其他项目花费的时间稍长。 所以选择第一个项目,然后立即选择第二个项目来重现场景,检查屏幕上显示的最喜爱的书籍 感谢您的帮助 服务代码: a

当通过下拉项选择上的$http angular service进行两次连续服务调用时,假设第一次调用花费时间返回,第二次调用在第一次调用解析之前返回,则显示第二次项目选择的第一次调用的数据

所以,若在第一次调用解决之前再次进行服务调用,是否有任何方法中止第一次承诺

为了演示的目的,我创建了一个带有几个项目的下拉列表,我添加了明确的条件,在选择第一个项目时,它比其他项目花费的时间稍长。 所以选择第一个项目,然后立即选择第二个项目来重现场景,检查屏幕上显示的最喜爱的书籍

感谢您的帮助

服务代码:

app.factory('bookService', function($http, $q, $timeout) {
  return {
    getBook: function(id) {
      var promise = $q.defer();
      var timeoutSpan = id == 1 ? 3000 : 500;
      $http.get("favouriteBooks.json").success(function(data) {
        $timeout(function() {
          promise.resolve(data.filter(function(obj) {
            return obj.id == id
          }));
        }, timeoutSpan);
      }).error(function(msg) {
        promise.reject(msg);
      })
      return promise.promise;
    }
  }
});

您可以使用以下命令等待两个或多个承诺
$q.all([promise1,promise2]),然后(function(data){……})


要访问第一个承诺的数据,只需使用
数据[0]
第二个承诺返回值保存在
数据[1]
中,依此类推……

您可以使用以下命令等待两个或多个承诺
$q.all([promise1,promise2])。然后(函数(数据){……}


要访问第一个承诺的数据,只需使用
数据[0]
第二个承诺返回值保存在
数据[1]
中,依此类推……

我找到了两种方法来处理这种情况-

案例1:在服务级别创建全局$q deffer对象,并在调用$http请求之前检查此对象是否有值。如果此deffer对象具有值,则显式解析它。普朗卡代码-

服务代码:

app.factory('bookService', function($http, $q, $timeout, bookConstants) {
  var service = {};
  service.mypromise = null;

  service.getBook = function(id) {
    if (service.mypromise) {
      service.mypromise.resolve(bookConstants.EXPLICIT_CANCEL);
      service.mypromise = null;
    }
    service.mypromise = $q.defer();
    var timeoutSpan = id == 1 ? 3000 : 500;
    $http.get("favouriteBooks.json").success(function(data) {
      $timeout(function() {
        if (service.mypromise) {
          service.mypromise.resolve(data.filter(function(obj) {
            service.mypromise = null;
            return obj.id == id
          }))
        }
      }, timeoutSpan);
    }).error(function(msg) {
      service.mypromise.reject(msg);
    })
    return service.mypromise.promise;
  }

  return service;

});
$scope.getSelectedValue = function() {
    var id = $scope.selitem.id
    $scope.cancel();
    var bookPromise = bookService.getBook(id);
    $scope.requests.push(bookPromise);
    bookPromise.promise.then(getBookSuccess)
      .catch(errorCallback)
      .finally(getBookComplete);
  }

  function getBookSuccess(favouriteBooks) {
    if (favouriteBooks == 'User Cancelled') {
      return;
    }

    var books = '';
    angular.forEach(favouriteBooks, function(book) {
      books += book.bookName + ' '
    });

    $scope.selectedvalues = 'Name: ' + $scope.selitem.name +
      ' Id: ' + $scope.selitem.id + ' Favourite Book(s): ' + books;
  }

  function errorCallback(errorMsg) {
    console.log('Error Message: ' + errorMsg);
  }

  function getBookComplete() {
    console.log('getBook Has Completed!');
  }

  $scope.cancel = function() {
    if ($scope.requests) {
      angular.forEach($scope.requests, function(request) {
        request.resolve('User Cancelled');
        clearRequest(request);
      })
    }
  };

  var clearRequest = function(request) {
    $scope.requests.splice($scope.requests.indexOf(request), 1);
  };

}]);

app.factory('bookService', function($http, $q, $timeout) {
  var service = {};
  service.getBook = function(id) {
    var promise = $q.defer();
    var timeoutSpan = id == 1 ? 3000 : 500;
    $http.get("favouriteBooks.json").success(function(data) {
      $timeout(function() {
        promise.resolve(data.filter(function(obj) {
          return obj.id == id
        }))
      }, timeoutSpan);
    }).error(function(msg) {
      promise.reject(msg);
    })
    return promise;
  }
  return service;
});
案例2:返回$q deffer对象作为服务响应,并将其保持在控制器级别。在连续服务调用的情况下,首先检查并明确解决第一个服务调用,然后继续其他服务调用。 普朗卡代码-

示例代码:

app.factory('bookService', function($http, $q, $timeout, bookConstants) {
  var service = {};
  service.mypromise = null;

  service.getBook = function(id) {
    if (service.mypromise) {
      service.mypromise.resolve(bookConstants.EXPLICIT_CANCEL);
      service.mypromise = null;
    }
    service.mypromise = $q.defer();
    var timeoutSpan = id == 1 ? 3000 : 500;
    $http.get("favouriteBooks.json").success(function(data) {
      $timeout(function() {
        if (service.mypromise) {
          service.mypromise.resolve(data.filter(function(obj) {
            service.mypromise = null;
            return obj.id == id
          }))
        }
      }, timeoutSpan);
    }).error(function(msg) {
      service.mypromise.reject(msg);
    })
    return service.mypromise.promise;
  }

  return service;

});
$scope.getSelectedValue = function() {
    var id = $scope.selitem.id
    $scope.cancel();
    var bookPromise = bookService.getBook(id);
    $scope.requests.push(bookPromise);
    bookPromise.promise.then(getBookSuccess)
      .catch(errorCallback)
      .finally(getBookComplete);
  }

  function getBookSuccess(favouriteBooks) {
    if (favouriteBooks == 'User Cancelled') {
      return;
    }

    var books = '';
    angular.forEach(favouriteBooks, function(book) {
      books += book.bookName + ' '
    });

    $scope.selectedvalues = 'Name: ' + $scope.selitem.name +
      ' Id: ' + $scope.selitem.id + ' Favourite Book(s): ' + books;
  }

  function errorCallback(errorMsg) {
    console.log('Error Message: ' + errorMsg);
  }

  function getBookComplete() {
    console.log('getBook Has Completed!');
  }

  $scope.cancel = function() {
    if ($scope.requests) {
      angular.forEach($scope.requests, function(request) {
        request.resolve('User Cancelled');
        clearRequest(request);
      })
    }
  };

  var clearRequest = function(request) {
    $scope.requests.splice($scope.requests.indexOf(request), 1);
  };

}]);

app.factory('bookService', function($http, $q, $timeout) {
  var service = {};
  service.getBook = function(id) {
    var promise = $q.defer();
    var timeoutSpan = id == 1 ? 3000 : 500;
    $http.get("favouriteBooks.json").success(function(data) {
      $timeout(function() {
        promise.resolve(data.filter(function(obj) {
          return obj.id == id
        }))
      }, timeoutSpan);
    }).error(function(msg) {
      promise.reject(msg);
    })
    return promise;
  }
  return service;
});

我找到了两种处理这种情况的方法-

案例1:在服务级别创建全局$q deffer对象,并在调用$http请求之前检查此对象是否有值。如果此deffer对象具有值,则显式解析它。普朗卡代码-

服务代码:

app.factory('bookService', function($http, $q, $timeout, bookConstants) {
  var service = {};
  service.mypromise = null;

  service.getBook = function(id) {
    if (service.mypromise) {
      service.mypromise.resolve(bookConstants.EXPLICIT_CANCEL);
      service.mypromise = null;
    }
    service.mypromise = $q.defer();
    var timeoutSpan = id == 1 ? 3000 : 500;
    $http.get("favouriteBooks.json").success(function(data) {
      $timeout(function() {
        if (service.mypromise) {
          service.mypromise.resolve(data.filter(function(obj) {
            service.mypromise = null;
            return obj.id == id
          }))
        }
      }, timeoutSpan);
    }).error(function(msg) {
      service.mypromise.reject(msg);
    })
    return service.mypromise.promise;
  }

  return service;

});
$scope.getSelectedValue = function() {
    var id = $scope.selitem.id
    $scope.cancel();
    var bookPromise = bookService.getBook(id);
    $scope.requests.push(bookPromise);
    bookPromise.promise.then(getBookSuccess)
      .catch(errorCallback)
      .finally(getBookComplete);
  }

  function getBookSuccess(favouriteBooks) {
    if (favouriteBooks == 'User Cancelled') {
      return;
    }

    var books = '';
    angular.forEach(favouriteBooks, function(book) {
      books += book.bookName + ' '
    });

    $scope.selectedvalues = 'Name: ' + $scope.selitem.name +
      ' Id: ' + $scope.selitem.id + ' Favourite Book(s): ' + books;
  }

  function errorCallback(errorMsg) {
    console.log('Error Message: ' + errorMsg);
  }

  function getBookComplete() {
    console.log('getBook Has Completed!');
  }

  $scope.cancel = function() {
    if ($scope.requests) {
      angular.forEach($scope.requests, function(request) {
        request.resolve('User Cancelled');
        clearRequest(request);
      })
    }
  };

  var clearRequest = function(request) {
    $scope.requests.splice($scope.requests.indexOf(request), 1);
  };

}]);

app.factory('bookService', function($http, $q, $timeout) {
  var service = {};
  service.getBook = function(id) {
    var promise = $q.defer();
    var timeoutSpan = id == 1 ? 3000 : 500;
    $http.get("favouriteBooks.json").success(function(data) {
      $timeout(function() {
        promise.resolve(data.filter(function(obj) {
          return obj.id == id
        }))
      }, timeoutSpan);
    }).error(function(msg) {
      promise.reject(msg);
    })
    return promise;
  }
  return service;
});
案例2:返回$q deffer对象作为服务响应,并将其保持在控制器级别。在连续服务调用的情况下,首先检查并明确解决第一个服务调用,然后继续其他服务调用。 普朗卡代码-

示例代码:

app.factory('bookService', function($http, $q, $timeout, bookConstants) {
  var service = {};
  service.mypromise = null;

  service.getBook = function(id) {
    if (service.mypromise) {
      service.mypromise.resolve(bookConstants.EXPLICIT_CANCEL);
      service.mypromise = null;
    }
    service.mypromise = $q.defer();
    var timeoutSpan = id == 1 ? 3000 : 500;
    $http.get("favouriteBooks.json").success(function(data) {
      $timeout(function() {
        if (service.mypromise) {
          service.mypromise.resolve(data.filter(function(obj) {
            service.mypromise = null;
            return obj.id == id
          }))
        }
      }, timeoutSpan);
    }).error(function(msg) {
      service.mypromise.reject(msg);
    })
    return service.mypromise.promise;
  }

  return service;

});
$scope.getSelectedValue = function() {
    var id = $scope.selitem.id
    $scope.cancel();
    var bookPromise = bookService.getBook(id);
    $scope.requests.push(bookPromise);
    bookPromise.promise.then(getBookSuccess)
      .catch(errorCallback)
      .finally(getBookComplete);
  }

  function getBookSuccess(favouriteBooks) {
    if (favouriteBooks == 'User Cancelled') {
      return;
    }

    var books = '';
    angular.forEach(favouriteBooks, function(book) {
      books += book.bookName + ' '
    });

    $scope.selectedvalues = 'Name: ' + $scope.selitem.name +
      ' Id: ' + $scope.selitem.id + ' Favourite Book(s): ' + books;
  }

  function errorCallback(errorMsg) {
    console.log('Error Message: ' + errorMsg);
  }

  function getBookComplete() {
    console.log('getBook Has Completed!');
  }

  $scope.cancel = function() {
    if ($scope.requests) {
      angular.forEach($scope.requests, function(request) {
        request.resolve('User Cancelled');
        clearRequest(request);
      })
    }
  };

  var clearRequest = function(request) {
    $scope.requests.splice($scope.requests.indexOf(request), 1);
  };

}]);

app.factory('bookService', function($http, $q, $timeout) {
  var service = {};
  service.getBook = function(id) {
    var promise = $q.defer();
    var timeoutSpan = id == 1 ? 3000 : 500;
    $http.get("favouriteBooks.json").success(function(data) {
      $timeout(function() {
        promise.resolve(data.filter(function(obj) {
          return obj.id == id
        }))
      }, timeoutSpan);
    }).error(function(msg) {
      promise.reject(msg);
    })
    return promise;
  }
  return service;
});

可能有助于您仅在响应第一个请求(同步您的请求)之后触发第二个AJAX请求。为了实现这一点,您可以使用加载符号或图像禁用下拉列表,直到收到第一个请求的响应。这是一个你可以尝试的解决方案。Karthik,要求不是从用户体验的角度限制用户采取行动。如果此问题没有解决方案,这将是最后一个选项。这可能有助于您仅在响应第一个请求(同步您的请求)后触发第二个AJAX请求。为了实现这一点,您可以使用加载符号或图像禁用下拉列表,直到收到第一个请求的响应。这是一个你可以尝试的解决方案。Karthik,要求不是从用户体验的角度限制用户采取行动。如果这个问题没有解决方案,这将是最后的选择。