Sunny-117/js-challenges

promise中断请求

Sunny-117 opened this issue · 3 comments

promise中断请求
// 根据promise a+ 规范来说
        // then()接受两个参数 如果参数是不是函数将被忽略
        // onFulfilled 将在promise fulfilled 后调用并接受一个参数
        // onRejected 将在promise rejected 后调用 并接受一个参数
        // 另外 then  一定返回的是promise
        // 若两参数是函数,当函数返回的是一个新的promise对象时
        //原promise 跟新promise 状态保持一致
        // 如果返回的promise 是个pending 状态 将保留直到转换为fulfilled / rejected
        //    
        // promise中断请求  不就是在then的时候将返回值新promise保持状态为penging
        // 那么这个promise 的链也将会中止(等待)

        Promise.resolve().then(()=>{
            // pending
            console.log(1)
            return new Promise(()=>{})
            // 后面的then 将不会调用
        }).then(()=>{
            console.log(2)
        })
let abort = false

function sendRequest() {
  return new Promise((resolve, reject) => {
    if (abort) {
      reject()
    }
    // 发送异步请求
    setTimeout(() => {
      resolve('result')
    }, 2000)
  })
}

setTimeout(() => {
  // 中断请求
  abort = true
}, 1000)

你这个写法不可能实现的吧,这个代码执行顺序是先执行
if (abort) {
reject()
}
然后再执行setTimeout函数里面的 abort = true,所以始终没有效果的

// 1.一个标准简单的promise
const promise = new Promise((resolve, reject) => {
  // ... some code
  if (/* 异步操作成功 */) {
    resolve(value)
  } else {
    reject(error)
  }
})

// 2.增加一个是否取消的promise判断
let cancelPromise = false
const promise = new Promise((resolve, reject) => {
  // ... some code
  if (/* 异步操作成功 */) {
    cancelPromise ? reject({isCanceled: true}) : resolve(value)
  } else {
    cancelPromise ? reject({isCanceled: true}) : reject(error)
  }
})

// 3.封装函数
// 3.1 第2步中内聚性不高,不符合高内聚,低耦合的代码原则。将其封装到同一个函数内
const makeCancelable = () => {
  let cancelPromise = false
  const wrappedPromise = new Promise((resolve, reject) => {
    // ... some code
    if (/* 异步操作成功 */) {
      cancelPromise ? reject({isCanceled: true}) : resolve(value)
    } else {
      cancelPromise ? reject({isCanceled: true}) : reject(error)
    }
  })

  return {
    promise: wrappedPromise,
    cancel() {
      cancelPromise: true
    }
  }
}

// 3.2 在第3.1步中,虽然函数可以设置操作取消promise了,但是promise执行操作的代码只能写在函数内部,不通用,将其改进,promise可传参
const makeCancelable = (promise) => {
  let cancelPromise = false
  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then((value) => {
      cancelPromise ? reject({isCanceled: true}) : resolve(value)
    })
    promise.catch((error) => {
      cancelPromise ? reject({isCanceled: true}) : reject(error)
    })
  })

  return {
    promise: wrappedPromise,
    cancel() {
      cancelPromise: true
    }
  }
}

// 4.举例使用可取消的promise
const somePromise = new Promise((resolve, reject) => {
  // ... some code
  if (/* 异步操作成功 */) {
    resolve(value)
  } else {
    reject(error)
  }
}) // 创建一个异步操作

const cancelable = makeCancelable(somePromise) // 为异步操作添加可取消的功能

cancelable.promise
  .then(() => console.log('resolved'))
  .catch(({isCanceled, ...error}) => console.log('isCanceled', isCanceled))

cancelable.cancel() // 取消异步操作

promise-async-await异步编程