8

Promise的基本使用

// 1. 创建一个新的promise对象  
// 1. 创建一个新的promise对象
  const p = new Promise((resolve, reject) => {// 执行器函数  同步回调
    console.log('执行 executor')
    // 2. 执行异步操作任务
    setTimeout(() => {
      const time = Date.now()
      // 3.1. 如果成功了, 调用resolve(value)
      if (time % 2 == 0) {
        resolve('成功的数据, time=' + time)
      } else {
        // 3.2. 如果失败了, 调用reject(reason)
        reject('失败的数据, time=' + time)
      }
    }, 1000);

  })
  console.log('new Promise()之后')

  p.then(
    value => { // 接收得到成功的value数据    onResolved
      console.log('成功的回调', value)
    },
    reason => {// 接收得到失败的reason数据  onRejected
      console.log('失败的回调', reason)
    }
  )
执行结果
执行 executor
new Promise()之后
失败的回调 失败的数据, time=1582696476447

为什么要用Promise

1. 指定回调函数的方式更加灵活
   纯回调函数: 必须在启动异步任务前指定  
   promise: 启动异步任务 => 返回promie对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定)  
2.支持链式调用, 可以解决回调地狱问题  
  什么是回调地狱? 回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调函数执行的条件  
  回调地狱的缺点?  不便于阅读 / 不便于异常处理  
  解决方案? promise链式调用  
  终极解决方案? async/await
function createAudioFileAsync() {}  
  
//执行函数  
function audioSettings() {}  
  
// 成功的回调函数  
function successCallback(result) {  
  console.log("声音文件创建成功: " + result);  
}  
// 失败的回调函数  
function failureCallback(error) {  
  console.log("声音文件创建失败: " + error);  
}  
  
/* 1.1 使用纯回调函数 */  
createAudioFileAsync(audioSettings, successCallback, failureCallback)  
  
/* 1.2. 使用Promise */  
const promise = createAudioFileAsync(audioSettings);  
//3秒后再绑定回调函数  
setTimeout(() => {  
  promise.then(successCallback, failureCallback);  
}, 3000);  
  
/*   
  2.1. 回调地狱  
  下一个回调函数依赖于上一个回调函数的执行结果,嵌套多层后,不便阅读  
 */  
doSomething(function(result) {  
  doSomethingElse(result, function(newResult) {  
    doThirdThing(newResult, function(finalResult) {  
      console.log('Got the final result: ' + finalResult)  
    }, failureCallback)  
  }, failureCallback)  
}, failureCallback)  
  
/*   
  2.2. 使用promise的链式调用解决回调地狱  
 */  
doSomething()  
  .then(function(result) {  
    return doSomethingElse(result)  
  })  
  .then(function(newResult) {  
    return doThirdThing(newResult)  
  })  
  .then(function(finalResult) {  
    console.log('Got the final result: ' + finalResult)  
  })  
  .catch(failureCallback)  
  
/*   
  2.3. async/await: 回调地狱的终极解决方案(ES7规范)  
 */  
async function request() {  
  try {  
    const result = await doSomething()  
    const newResult = await doSomethingElse(result)  
    const finalResult = await doThirdThing(newResult)  
    console.log('Got the final result: ' + finalResult)  
  } catch (error) {  
    failureCallback(error)  
  }  
}

Promise的API

1. Promise构造函数: Promise (executor) {}  
   executor函数: 同步执行 (resolve, reject) => {} 
   resolve函数: 内部定义成功时调用的函数 value => {} 
   reject函数: 内部定义失败时调用的函数 reason => {} 
   说明: executor会在Promise内部立即同步回调,异步操作在执行器中执行  
 
2. Promise.prototype.then方法: (onResolved, onRejected) => {}  
   onResolved函数: 成功的回调函数  (value) => {} 
   onRejected函数: 失败的回调函数 (reason) => {} 
   说明: 指定用于得到成功value的成功回调和用于得到失败reason的失败回调 返回一个新的promise对象  

3. Promise.prototype.catch方法: (onRejected) => {}  
   onRejected函数: 失败的回调函数 (reason) => {} 
   说明: then()的语法糖, 相当于: then(undefined, onRejected)  
 
4. Promise.resolve方法: (value) => {}  
   value: 成功的数据或promise对象 
   说明: 返回一个成功/失败的promise对象 

5. Promise.reject方法: (reason) => {}  
   reason: 失败的原因 
   说明: 返回一个失败的promise对象  
 
6. Promise.all方法: (promises) => {}  
   promises: 包含n个promise的数组 
   说明: 返回一个新的promise, 只有所有的promise都成功才成功, 只要有一个失败了就直接失败  
 
7. Promise.race方法: (promises) => {}  
   promises: 包含n个promise的数组 
   说明: 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态
new Promise((resolve, reject) => {  
  setTimeout(() => {  
    // resolve('成功的数据')  
  reject('失败的数据')  
  }, 1000)  
}).then(  
  value => {  
    console.log('onResolved()1', value)  
  }  
).catch(  
  reason => {  
    console.log('onRejected()1', reason)  
  }  
)  
  
// 产生一个成功值为1的promise对象  
const p1 = new Promise((resolve, reject) => {  
  setTimeout(() => {  
    resolve(1)  
  }, 100);  
})  
  
//产生一个成功值为2的promise对象  
const p2 = Promise.resolve(2)  
  
//产生一个失败值为3的promise对象  
const p3 = Promise.reject(3)  
  
p1.then(value => {console.log(value)}) // 1  
p2.then(value => {console.log(value)}) // 2  
p3.catch(reason => {console.log(reason)}) // 3  
  
//只有全部的promise都成功才会成功,values为数组,只要有一个失败,就会失败  
const pAll = Promise.all([p1, p2, p3])  
pAll.then(  
  values => {  
    console.log('all onResolved()', values)  
  },  
  reason => {  
    console.log('all onRejected()', reason)  
  }  
)  
  
//返回第一个成功的promise  
const pRace = Promise.race([p1, p2, p3])  
pRace.then(  
  value => {  
    console.log('race onResolved()', value)  
  },  
  reason => {  
    console.log('race onRejected()', reason)  
  }  
)
代码已同步更新到github上

https://github.com/hnt815/promise

Promise系列文章

Promise从两眼发懵到双眼放光(1)-准备篇
Promise从两眼发懵到双眼放光(2)-Promise基础
Promise从两眼发懵到双眼放光(3)-Promise的几个关键问题(一)
Promise从两眼发懵到双眼放光(4)-Promise的几个关键问题(二)
Promise从两眼发懵到双眼放光(5)-手写Promise之整体结构
Promise从两眼发懵到双眼放光(6)-手写Promise之构造函数
Promise从两眼发懵到双眼放光(7)-手写Promise之then方法和catch方法
Promise从两眼发懵到双眼放光(8)-手写Promise之resolve,reject,all,race方法
Promise从两眼发懵到双眼放光(9)-async和await


ntyang
165 声望29 粉丝

非典型性代码搬运工,搞点儿事情