一个笨蛋前端

好好学习,天天向上

基于Promise的函数封装

在promise的 多次网络请求中 我们经常会遇到一个场景就是
网络请求对象本身就是一个promise对象了
但是我需要进行几次then之后的返回一个promise 给下一步网络请求调用,直接直接链式写 那么势必又臭又长!

ajax1.then(1).then(2).then(3=>return ajax21)
.then(ajax22).then(ajax23)

所以 如何把一个promise的执行过程封装成一个函数呢?

例如 上例

func ajax1<=>ajax1.then(1).then(2).then(3)
func ajax2<=>ajax21.then(ajax22).then(ajax23)

然后我用调用的时候就是

ajax1.then(return ajax2).catch()

Promise-based API 的函数

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

function fetch_current_data() {
  // fetch() API 返回了一个 Promise.
  // 这个函数提供了类似的API,
  // 这个函数除了实现 Promise,它还能够完成更多的工作。
  return fetch('current-data.json').then((response) => {
    if (response.headers.get('content-type') != 'application/json') {
      throw new TypeError();
    }
    var j = response.json();
    // maybe do something with j
    return j; // fulfillment value given to user of
              // fetch_current_data().then()
  });
}

上面的例子呢 我们可以把一个promise过程封装成一个函数调用fetch_current_data().then()

但是如何组合我们的多个promise过程

因为promise中的then return可以返回一个promise
如类似上面的例子我们可以粗暴的组装成

fetch_current_data().then(return fetch_current_data2)

但是还有一个问题 如何catch?

如果上面的then操作本身出现了问题,或者fetch的API请求出现了问题?

一般情况下我们可以这样解决
function fetch_current_data() {
  // fetch() API 返回了一个 Promise.
  // 这个函数提供了类似的API,
  // 这个函数除了实现 Promise,它还能够完成更多的工作。
  return fetch('current-data.json').then((response) => {
    if (response.headers.get('content-type') != 'application/json') {
      throw new TypeError();
    }
    var j = response.json();
    // maybe do something with j
    return j; // fulfillment value given to user of
              // fetch_current_data().then()
  });
}.catch(e=>{//todo})

但是问题来了fetch_current_data().then(return fetch_current_data2)这种基于promise的函数调用的时候 就会出现问题了

catch后面的catch会依次执行

fetch_current_data().then(return fetch_current_data2).catch(e=>{//todo})这种格式的基于promise的函数连续调用最终会变成

//fetch_current_data
fetch('current-data.json')
  .then((response) => {
   //return todo
  })
  .catch(e=>{//todo})
  .then(
      //fetch_current1_data
      return fetch(current-data1.json) 
      .then()
      .catch(e=>{//todo})
  ).catch(e=>{
  //连续的三个catch都会执行
  })

注意 当其中的第一个catch报错的时候 会触发会后一个catch

当然这种情况下 其实用async的效果更好 直观

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注