使用 promise 调用 Ajax 而无需重复代码

Using promise to call Ajax without duplicating code

这可能吗?我想写一个 ajax 函数,我不想复制它。向它传递不同的参数,这些参数是不同文件的位置。然后使用 promise 使它们成为一个对象。我可能会使用传播运算符。这可能吗

var myFuncCalls = 0;

let promiseAjax = new Promise (function ( resolve,reject) {

//possibly use a for look to grab the number of times the loadDoc was called then call the same function and send it to may be an array?
    function loadDoc(location) {
        myFuncCalls++;
        console.log("loadDoc was called :" + myFuncCalls);



        var xyz = new XMLHttpRequest();
        xyz.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                //console.log(this.responseText)
                resolve(this.responseText);          
            }
        };

        xyz.open("GET", location, true);
        xyz.send();
    }

    loadDoc("/_js/someitems.json");
    loadDoc("/_js/someMoreItems.json");
})

// then grab all that stuff and make one single object using spread operators
promiseAjax.then(function (fromResolve){

    // JSON.parse(fromResolve);
    var newObj = JSON.parse(fromResolve);
    console.log(newObj);

})

我认为最简单的事情是定义异步函数,return 承诺并且可以轻松传递和重用。

您可以这样做:

async function loadFile(file) {
   ...
   return {...fileJSON};
}

async function loadFiles() {
    const file1JSON = await loadFile('file1');
    const file2JSON = await loadFile('file2');
    return {...file1JSON, ...file2JSON};
}

loadFiles().then((combinedJSON) => {
  ...
})

这些函数可以接受参数并像任何其他函数一样重复使用。

是的,您可以将 URL、任何参数,甚至 AJAX 调用的类型(POST、GET 等)发送到该方法,然后使用它来构建电话。这样,您可以通过“简单”方法调用重用相同的方法来执行您需要从客户端执行的任何操作。

此答案中的所有代码均复制自以下link。

https://medium.com/front-end-weekly/ajax-async-callback-promise-e98f8074ebd7

function makeAjaxCall(url, methodType)
{
 var promiseObj = new Promise(function(resolve, reject)
 {
  var xhr = new XMLHttpRequest();
  xhr.open(methodType, url, true);
  xhr.send();
  xhr.onreadystatechange = function()
  {
   if (xhr.readyState === 4)
   {
    if (xhr.status === 200)
    {
     console.log("xhr done successfully");
     var resp = xhr.responseText;
     var respJson = JSON.parse(resp);
     resolve(respJson);
    }
    else
    {
     reject(xhr.status);
     console.log("xhr failed");
    }
   }
   else {console.log('xhr processing going on');}
  }
  console.log("request sent succesfully");
 });
 return promiseObj;
}
enter code here
document.getElementById('userDetails').addEventListener('click', function()
{
 // git hub url to get btford details
 var userId = document.getElementById("userId").value;
 var URL = "https://api.github.com/users/"+userId;
 makeAjaxCall(URL, "GET").then(processUserDetailsResponse, errorHandler);
});

您甚至可以将回调方法发送给它。我还向它发送了一个用于错误的方法。

function makeAjaxCall(url, methodType, callback)
{
  $.ajax(
  {
   url : url,
   method : methodType,
   dataType : "json",
   success : callback,
   error : function (reason, xhr){
   console.log("error in processing your request", reason);
  }
 });
}
// git hub url to get btford details
var URL = "https://api.github.com/users/btford";
makeAjaxCall(URL, "GET", function(respJson)
{
 document.getElementById("userid").innerHTML = respJson.login;
 document.getElementById("name").innerHTML = respJson.name;
 document.getElementById("company").innerHTML = respJson.company;
 document.getElementById("blog").innerHTML = respJson.blog;
 document.getElementById("location").innerHTML = respJson.location;
});

使用 Promise.all() 将两个调用放在一起,这样您就可以使用您解析的数据数组。

function loadDoc(location) {
  return new Promise (function ( resolve,reject) {
    var xyz = new XMLHttpRequest();
    xyz.onreadystatechange = function () {
      if (this.readyState == 4 && this.status == 200) {
        resolve(this.responseText);          
      }
    };
    xyz.open("GET", location, true);
    xyz.send();
  });
}

const urls = ["/_js/someitems.json", "/_js/someMoreItems.json"]
Promise.all(urls.map(url=>loadDoc(url))).then(responses =>
  console.log(responses);
)

这种行为可以用 Promise.all Promise.all white the use of async+await async 归档,并且使用更多最先进的调用 (fetch) 使代码看起来更清晰

async function loadAll(docs) {
    return Promise.all(docs.map(async doc => {
        const result = await fetch('http://example.com/movies.json');
        return result.json();
    }));
}

(async function() {
    const responses = await loadAll(["/_js/someitems.json", "/_js/someMoreItems.json"]);
    console.log(responses);
})();

注意:await 只能在异步函数中使用。 注2:代码未经测试

Promise.allObject.assign,

function loadDoc(location) {
  return new Promise((resolve, reject) => {
    var xyz = new XMLHttpRequest();
    xyz.onreadystatechange = () => {
      if (this.readyState == 4 && this.status == 200) {
        resolve(JSON.parse(this.responseText));
      } else {
        // resolving with empty object to avoid breaking other fetch if one failed
        resolve({});
      }
    };

    xyz.open("GET", location, true);
    xyz.send();
  });
}

const loadDocs = (paths) => Promise.all(paths.map(path => loadDoc(path))
  .then(results => {
    // combine all result into single object
    return Object.assign({}, ...results);
  }));

// example
loadDocs([
  "/_js/someitems.json",
  "/_js/someMoreItems.json"
]).then(function(finalCombinedObject) {
  // other logic here
});