简体   繁体   中英

How to return a new promise instead of an error on a failed ajax request in Javascript/Jquery?

I have a function which creates a deferred object. On fail I'm calling a fallback function, which in turn creates and returns it's own deferred/promise object. I would like to return the result of this fallback- deferred but I'm only able to return the error on my initial call.

Here is what I'm doing:

 // method call
 init.fetchConfigurationFile(
      storage,
      "gadgets",
      gadget.getAttribute("data-gadget-id"),
      pointer
  ).then(function(fragment) {
      console.log("gotcha");
      console.log(fragment);
  }).fail(function(error_should_be_fragment) {
      console.log("gotcha not");
      console.log(error_should_be_fragment);
  });

My fetchConfiguration call tries to load from localstorage and falls back to loading from file if the document/attachment I need is not in localstorage.

  init.fetchConfigurationFile = function (storage, file, attachment, run) {
    return storage.getAttachment({"_id": file, "_attachment": attachment})
      .then(function (response) {
        return jIO.util.readBlobAsText(response.data);
      })
      .then(function (answer) {
        return run(JSON.parse(answer.target.result))
      })
      .fail(function (error) {
        // PROBLEM
        console.log(error);
        if (error.status === 404 && error.id === file) {
          return init.getFromDisk(storage, file, attachment, run);
        }
      });
  };

My problem is I can catch the 404 allright, but instead of returning the error object, I would like to return the promise generated by init.getFromDisk .

Question :
Is it possible to return the result of my getFromDisk call in the error handler? If not, how would I have to structure my calls so that I'm always returning a promise to my first method call?

Thanks for help!

SOLUTION :
Thanks for the help! Fixed it like this:

 init.fetchConfigurationFile(
      storage,
      "gadgets",
      gadget.getAttribute("data-gadget-id"),
      pointer
    ).always(function(fragment) {
      console.log("gotcha");
      console.log(fragment);
    });

init.fetchConfigurationFile = function (storage, file, attachment, run) {
  return storage.getAttachment({"_id": file, "_attachment": attachment})
    .then(function (response) {
      return jIO.util.readBlobAsText(response.data);
    })
    .then(
      function (answer) {
        return run(JSON.parse(answer.target.result));
      },
      function (error) {
        if (error.status === 404 && error.id === file) {
          return init.getFromDisk(storage, file, attachment, run);
        }
      }
    );
};

.fail() always returns the original promise.

You should call then() with a failure callback to allow chaining:

.then(undefined, function(error) {
    return ...;
});

Before jQuery 1.8, use .pipe() instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM