回调地域 与 Promise

1.什么是回调地域?

回调地狱的概念:回调函数里面嵌套回调函数。(问题解决慢慢看)

//需求: 向某位女生发送短信
/**
 * @description: name:女神名字 onFulffiled成功后的回调 onRejected失败后的回调
 * @return {*}
 * @author: 前端33号笔记员
 */
function sendMessage(name, onFulffiled, onRejected) {
  console.log('我:' + name + '我喜欢你');
  setTimeout(() => {
    if (Math.random() <= 0.1) {
      // 成功
      onFulffiled('女神:我也喜欢你!')
    } else {
      onRejected('女神:我老公不同意!')
    }
  }, 1000);
}

// 只追小美
sendMessage('小美', (message) => {
  console.log('成功', message);
}, (message) => {
  console.log('失败', message);
})

/**
 * @description: 需求,有4位女生,小美,小蓝,小红,小花,一个一个追,不同意就追下一个!
 * @return {*} 下面代码就是回调地域
 * @author: 前端33号笔记员
 */

sendMessage('小美', (message) => {
  console.log('成功', message);
}, (message) => {
  console.log('失败', message);
  // 追小蓝
  sendMessage('小蓝', (message) => {
    console.log('成功', message);
  }, (message) => {
    console.log('失败', message);
    // 追小红
    sendMessage('小红', (message) => {
      console.log('成功', message);
    }, (message) => {
      console.log('失败', message);
      // 追小花
      sendMessage('小花', (message) => {
        console.log('成功', message);
      }, (message) => {
        console.log('失败', message);
      })
    })
  })
})


2.Promise 规范

1. 所有的异步场景,都可以看做是一个异步任务,每个异步任务,在JS中应该表现为一个对象,该对象被称为Promise对象,也叫任务对象

2.每个任务对象,都应该有两个阶段、三个状态

未决阶段就是没有结果的阶段(例如:发送账号密码到服务器,还没通知是否正确的阶段) 

已决阶段就是有结果的阶段(例如:通知账号密码正确或失败)

根据常理,他们之间存在以下步骤:

1.任务总是从未决阶段变到已决阶段,无法逆行

2.任务总是从挂起状态变到完成或失败状态,无法逆行

3.任务一旦完成或失败,状态就固定下来了,永远无法改变

 3.挂起到完成,称之为 resolve;挂起到失败,称之为 reject;任务完成时,可能有一个相关数据,任务失败时,可能有一个失败原因

4.可以针对任务进行后续处理,针对完成状态的后续处理称之为onFulfilled,针对失败的后续处理称之为onRejected

3.Promise API (es6提供) 基础使用

// 创建了一个异步任务(任务总是从未决阶段变到已决阶段,无法逆行),所以状态是pending
const pro = new Promise((resolve, reject) => {
  console.log('百米赛跑');
  const duration = Math.floor(Math.random() * 5000)

  setTimeout(() => {
    if (Math.random() < 0.5) {
      resolve(duration)
    } else {
      reject('脚伤了')
    }
  }, duration)
})

pro.then((data) => {
  console.log("跑了", data, '秒');
}, (reason) => {
  console.log('不好意思', reason);
})

改造回掉地狱问题 第一步:

function sendMessage(name) {
  return new Promise((resolve, reject) => {
    console.log('我:' + name + '我喜欢你');
    setTimeout(() => {
      if (Math.random() <= 0.1) {
        // 成功
        resolve('女神:我也喜欢你!')
      } else {
        reject('女神:我老公不同意!')
      }
    }, 1000);
  })
}

// 只追小美
sendMessage('小美').then((data) => {
  console.log('成功', data);
}, (reason) => {
  console.log('失败', reason);
})

4.Promise 链式调用

1.then方法必定会返回一个新的promise

2.新任务状态取决于后续处理

1.若没有相关的后续处理,新任务的状态和前任务保持一致,数据为前任务的数据

const pro = new Promise((resolve, reject) => {
  console.log(1);
  resolve(123) //成功了 数据123
})

// 对pro只进行了 失败处理
const pro2 = pro.catch(() => {
  console.log(2);
})

setTimeout(() => {
  console.log(pro2);//那么新任务状态和前任务状态一样,数据也是123
}, 1000)

2.若有后续处理,但是还未执行,新任务挂起

const pro = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(123) //2秒之后失败
  }, 2000)
})

// 对pro只进行了 失败处理
const pro2 = pro.catch(() => {
  console.log(2);
})

setTimeout(() => {
  console.log(pro2);//一秒输出 pro2未执行所以挂起状态
}, 1000)

3.若后续处理执行了,则根据后续处理的情况确定新任务状态

  • 后续处理无错,新任务状态完成,数据为后续处理的返回值
  • 若后续处理执行有错,新任务状态为失败,数据为异常对象
  • 后续执行后返回的是一个任务对象,新任务的状态和数据与该任务对象一致
  • const pro = new Promise((resolve, reject) => {
      resolve()//成功了,
    })
    
    // 对pro只进行了 成功
    const pro2 = pro.then(() => {
      console.log(2);
      // return 100  //没错误 状态为完成 返回值100
      // throw new Error('出错了')//有错误状态为失败,数据为异常对象
      return new Promise(() => {}) //返回一个任务对象,在未决阶段,所以pro2 状态pending
    })
    
    setTimeout(() => {
      console.log(pro2);
    }, 1000)
    

 改造回掉地狱问题(后面继续优化):

function sendMessage(name) {
  return new Promise((resolve, reject) => {
    console.log('我:' + name + '我喜欢你');
    setTimeout(() => {
      if (Math.random() <= 0.1) {
        // 成功
        resolve('女神:我也喜欢你!')
      } else {
        reject('女神:我老公不同意!')
      }
    }, 1000);
  })
}

// 小美,小蓝,小红,小花,
sendMessage('小美').catch((reason) => {
  console.log(reason);
  return sendMessage('小蓝')
})
  .catch((reason) => {
    console.log(reason);
    return sendMessage('小红')
  })
  .catch((reason) => {
    console.log(reason);
    return sendMessage('小花')
  })
  .then((reply) => {
    console.log(reply);
  }, (reply) => {
    console.log(reply);
  })

5.async与await

async关键字用于修饰函数,被他修饰的函数,一定返回Promise

await 关键字表示等待某个Promise完成,它必须用于async函数中

await作用是等待一个异步的成功结果,并且会阻塞代码在这个作用域await之后的代码,会将他们加入微任务。async是声明一个异步函数。相当于promise的简写。一般搭配await使用。async await优点是可以优雅编写异步操作。缺点是会阻塞

解决回调地域的问题:

async function sendMessage(name) { 
  // 若返回的是Promise,则方法得到的Promise状态一致(也就是说 这个函数的async可以省略)
  return new Promise((resolve, reject) => {
    console.log('我:' + name + '我喜欢你');
    setTimeout(() => {
      if (Math.random() <= 0.3) {
        // 成功
        resolve('女神:我也喜欢你!')
      } else {
        reject('女神:我老公不同意!')
      }
    }, 1000);
  })
}

let beautyGirls = ['小美', '小蓝', '小红', '小花'];

  (async () => {
    for (const name of beautyGirls) {
      try {
        const reply = await sendMessage(name)
        // 表白成功 跳出循环
        console.log(reply);
        break;
      } catch (error) {
        // 表白失败
        console.log(error);
      }
    }
  })()

  • 29
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值