How to Improve The axios.spread

醉酒当歌 提交于 2019-12-10 10:52:43

问题


The below code i use for doing multiple HTTP calls depending on the studentList.

It works well; however, I think the axios spread is not necessary

export default {

      getFee (studentList: { studentId: string }[]) {

        if (studentList.length < 1) {
          Promise.resolve()
        }
        let promises = []
        for (const student of studentList) {
          if (!student.studentId) {
            Promise.resolve()
          }
          var url = `${API_URL}/${student.studentId}`

          promises.push(Axios.get(url))
        }

        return Axios.all(promises)
          .then(Axios.spread((...args) => {
            // customise the response here
            return args
              .map(response => response.data)
              .map(data => {
                // @ts-ignore
                data.totalMark = data.markinPhysics + data.markinMaths + data.markinChemistry // total mark  sum of marks in differnet discplines
                return data
              })
          }))
          .catch(error => {
            switch (error.response.status) {
              case 400:
                console.log('student not found')
                break
              case 500:
                console.log('error invoking')

                break
              default:
                console.log('unknown error')

I have to do multiple network calls in Vue and I am using Axios.

I got it working by axios, all and axios.spread, but I think the code can be improved.

The logic is to do multiple calls for the student list and get the outputs back

Can anyone help?


回答1:


Axios.all

as well as Promise.all accepts array of promises and returns a new Promise which is resolved whenever all of the given promises are resolved with an array with the result of each promise

e.g.

const promise1 = Promise.resolve('data1');
const promise2 = Promise.resolve('data2');

Promise.all([
  promise1,
  promise2,
]).then(results => {
  // results is an array with 2 elements
  console.log(results[0]); // data1
  console.log(results[1]); // data2
});

you can use Axios.spread to to assign each result to a variable like this:

Promise.all([
  promise1,
  promise2,
]).then(Axios.spread(( result1, result2 ) => {
  // args is an array with 2 elements
  console.log(result1); // data1
  console.log(result2); // data2
});

alternatively you can use ES6 Destructuring assignment:

Promise.all([
  promise1,
  promise2,
]).then(([ result1, result2 ]) => {
  // args is an array with 2 elements
  console.log(result1); // data1
  console.log(result2); // data2
});

Unnecessary Promise.resolve()

Your Promise.resolve() function calls have no effect on the getFee method since you're not returning them

What would my implementation be

async function getFee(studentList) {
  try {
    const promises = studentList.reduce((acc, student) =>
      student.studentId
        ? acc.concat(Axios.get(`${API_URL}/${student.studentId}`))
        : acc
    , []);

    const responses = await Axios.all(promises);

    return responses
      .map(response => response.data)
      .map(data => ({
        // return new object
        // with data's properties
        // instead of assinging the new ones directly to the data
        ...data,
        // total mark  sum of marks in differnet discplines
        totalMark: data.markinPhysics + data.markinMaths + data.markinChemistry,
      }));
  } catch (error) {
    switch (error.response.status) {
      case 400:
        console.log("student not found");
        break;
      case 500:
        console.log("error invoking");
        break;
      default:
        console.log("unknown error");
    }
  }
}

export default {
  getFee
}



回答2:


Since you're only using args as an array, you could remove axios.spread.

axios.spread() might only be useful in older browsers now that ES2015 introduced its own spread operator. The main purpose of axios.spread() is to expand the result of axios.all() into an argument list, such that you could do:

axios.all(promiseArray).then(axios.spread(function(arg1, arg2, arg3) {
  /*...*/
}))

instead of:

axios.all(promiseArray).then(function(args) {
  var arg1 = args[0]
  var arg2 = args[1]
  var arg3 = args[2]
  /*...*/
})

ES2015's rest operator does the inverse of axios.spread(), so when you combine them (as seen below), you end up with the result above, as if axios.spread() and the rest operator weren't even used:

axios.all(promiseArray).then(axios.spread(function(...args) {
  var arg1 = args[0]
  var arg2 = args[1]
  var arg3 = args[2]
  /*...*/
}))

// or newer syntax:

axios.all(promiseArray).then(axios.spread((...args) => {
  const arg1 = args[0]
  const arg2 = args[1]
  const arg3 = args[2]
  /*...*/
}))



回答3:


To avoid promise chaining and improve readability, I think below can be used.

const [arg1, arg2] = await Promise.all(promises)


来源:https://stackoverflow.com/questions/56116421/how-to-improve-the-axios-spread

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!