【问题标题】:How to account for errors in the ajax calls when using alternative promises使用替代承诺时如何解决 ajax 调用中的错误
【发布时间】:2016-08-19 02:02:44
【问题描述】:

在构建将根据用户的位置坐标提供天气数据的应用程序时,我开发了以下代码(也可在此代码笔http://codepen.io/PiotrBerebecki/pen/QNVEbP 中找到)。

用户的位置将由getCoordinatesMethod1() 函数传递。但是,如果此操作失败,则应通过 getCoordinatesMethod2() 函数传递位置。

如何将getCoordinatesMethod2() 添加到promise 链(在底部),以便仅在getCoordinatesMethod1() 未能提供位置时使用?

此外,将来为了使应用程序更健壮,我可能会添加更多方法来获取位置数据,因此链逻辑也应该能够适应这种情况。

// The first method to get user location coordinates.
function getCoordinatesMethod1() {
  return $.ajax('http://wwww.example.com/coordinates-method-1.json');
}

// The second method to get user location coordinates.
// This should only be used if method 1 fails to deliver coordinates.
function getCoordinatesMethod2() {
  return $.ajax('http://wwww.example.com/coordinates-method-2.json');
}

// Function which provides weather data depending on user coordinates.
function getCurrentWeather(latitude, longitude) {
  return $.ajax('http://www.example.com/lat=' + latitude + '&lon=' + longitude + 'weather.json');
}

// Promises chain
getUserCoordinates1().then(function(locationData) {
  return getCurrentWeather(locationData);
  }).then(function(weatherData) {
    return showCurrentWeather(weatherData);
  })

【问题讨论】:

  • 你使用的是 jQuery 3 还是早期版本的 promises?
  • 目前我使用的是 jQuery 2.2.2。

标签: javascript jquery ajax asynchronous promise


【解决方案1】:

您可以创建一个调用第一个方法的函数,如果返回 promise 拒绝,则调用第二个方法:

function getCoordinateBoth() {
   return getCoordinatesMethod1().then(null, getCoordinatesMethod2);
}

如果确实有参数传递给这些函数,那么您可以像这样传递这些参数:

function getCoordinateBoth(/* args here */) {
   var args = Array.prototype.slice.call(arguments);
   return getCoordinatesMethod1.apply(null, args).then(null, function() {
       return getCoordinatesMethod2.apply(null, args)    
   });
}

您甚至可以将这些函数放在一个数组中,这样它就可以无限扩展:

// Put list of functions to be call as a chain until one succeeds
// You can just add more functions here as long as each returns a promise
//    and expects the same arguments
var getCoordFunctions = [getCoordinatesMethod1, getCoordinateMethod2, getCoordinateMethod3];

function getCoordinateChain(/* args here */) {
   var args = Array.prototype.slice.call(arguments);
   var fnArray = getCoordFunctions.slice(0);
   var firstFn = fnArray.shift();
   fnArray.reduce(function(p, fn) {
        return p.then(null, function() {
            return fn.apply(null, args);
        });
   }, firstFn.apply(null, arguments));
}

你甚至可以把它变成一个通用的承诺链函数:

function chainUntilResolve(array /* other args here */) {
   var args = Array.prototype.slice.call(arguments);
   // toss first arg
   args.shift();
   // make a copy of array of functions
   var fnArray = array.slice(0);
   // remove first function from the array
   var firstFn = fnArray.shift();
   fnArray.reduce(function(p, fn) {
        return p.then(null, function() {
            return fn.apply(null, args);
        });
   }, firstFn.apply(null, arguments));
}


var getCoordFunctions = [getCoordinatesMethod1, getCoordinateMethod2, getCoordinateMethod3];

chainUntilResolve(getCoordFunctions, arg1, arg2).then(function(data) {
    // process data here
}, function(err) {
    // error here
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2019-03-31
    • 1970-01-01
    • 2021-06-11
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多