半明白系列--Promise的进化史

半明白系列–Promise的进化史

学过js的都晓得,顺序有同步编程和异步编程之分,同步就比方流水线,一步一个脚印,做完上个使命才做下一个,异步编程比方客服,客服接了一个电话,收到了一个使命,然后把使命交给别的的人来处置惩罚,同时,继承接听下一个电话,比及别的的人处置惩罚完使命了,再关照客服,客服再反馈给第一个打电话的人。异步编程平常用来调取接口拉数据。

经由过程我形貌的篇幅,就晓得异步编程比同步编程贫苦很多。太古时代,异步编程是经由过程回调函数来处理的。然则回调函数会有回调地狱的题目,回调的多了,保护职员看起来头都大了,比方:taskC须要守候taskB做完(taskC才实行),taskB又须要守候taskA做完(taskB才实行)

function taskA (cb) {
  //..do task A
  cb()
}
function taskB(cb){
  //..do task B
  cb()
}
function taskC(cb){
  //..do task C
  cb()
}
taskA(function(){
  taskB(function(){
    taskC()
  })
})
...以此类推,不停轮回嵌套,终究堕入地狱

而Promise就把这一系列的回调,经由过程链式挪用的体式格局连接起来,看起来清新多了。同样是上面的代码,Promise能够这么写(伪代码)

new Promise().then(taskA).then(taskB).then(taskC)

promise的运用

const promise = new Promise((resolve,reject)=>{
  if (/*do something done*/){
    resolve() // 可在此传参数
  } else {
    // do something fail
    reject() // 可在此传参数
  }
})
promise.then(()=>{
  //do something
}).catch(e => { throw e})

上面的resolve,能够看成task函数的cb回调函数,当resolve()实行的时刻,then要领中的回调会被实行,如果是reject实行,毛病会被catch捕捉。

Promise的静态要领

上面说的thencatch都是Promise的原型要领,即Promise.prototype.then/catch
Promise自身有两个静态要领,其作用类似 new Promise()

Promise.resolve()

const promise1 = Promise.resolve()

等价于

const promise2 = new Promise((reslove)=>{
  reslove()
})

运用该要领挪用then要领
Promise.reject()

const promise1 = Promise.reject()

等价于

const promise2 = new Promise((resolve,reject)=>{
  reject()
})

运用该要领会被catch捕捉

Promise的链式挪用

Promise的实例对象的then要领是能够反复挪用的,then要领返回的是一个promise实例对象,所以能够反复挪用then要领,而且(敲黑板),上一个then要领的返回值,会作为下一个then要领的参数通报

举个栗子:

const promise = Promise.resolve('start')

promise.then((params)=>{
  console.log(params) // start
  return 'aa'
}).then((params) => {
  console.log(params) // aa
  return 'bb'
}).then((params)=>{
  console.log(params) // bb
  return 'cc'
})

// 最后会返回一个状况是resolve(cc)的promise对象:Promise {<resolved>: "cc"}

深切一下(又不会怀胎)

function badAsyncCall() {
  var promise = Promise.resolve();
  promise.then(function() {
      // 恣意处置惩罚
      return 'newVar';
  });
  return promise;
}
// 修正一下
function goodAsyncCall() {
  var promise = Promise.resolve();
  return promise.then(function() {
      // 恣意处置惩罚
      return 'newWar';
  });
}

以上两个写法是否是很类似,唯一差别的就是return的处置惩罚。但挪用,badAsynccall会失足,而anAsyncCall能准确实行,比方:

badAsyncCall().then(params => { console.log('bad--',params)}) // bad-- undefined
goodAsyncCall().then(params => { console.log('good--',params)}) // good-- newWar

剖析:第一种,毛病写法,首先在 promise.then 中发生的非常不会被外部捕捉,另外,也不能获得 then 的返回值,即使其有返回值。
缘由:因为每次 promise.then 挪用都邑返回一个新创建的promise对象,第一种返回的promise,相当于没有挪用过函数内部的then要领,是一个全新的promise实例对象
结论: 一致运用promise链式挪用,如:promise.then(taskA).then(taskB)

### async&await和promise的宿世缘缘

promise说白了照样用回调的体式格局来处理异步题目,跟真正同步照样有差异的。
异步编程的最高境地,就是基础不必体贴它是否是异步!(来之ruanyifeng先生的话)

所以,async&await计划涌现了

用法:

function readFile(fileName) {
  return new Promise((resolve,reject)=>{
    fs.readFile(fileName, function(error, data) {
      if (error) return reject(error);
      resolve(data); // 向thenc传送异步读取文件的数据
    });
  })
}

// 挪用

readFile(fileName).then(function(data){
  console.log('prmoise read files data --', data)
})


// 等价于

async function asyncFn(fileName){
  const data = await readFile(fileName)
  console.log('await data --', data)
  return data
}

asyncFn(fileName) 

写法是否是简约了很多!
实在async就是一个Promise的语法糖,它的返回值是一个promise对象,因而能够用then要领做链式挪用(但参数就是async函数中的返回值,如上文的data!!)

async函数中还能够不运用promise,比方:

async function asyncFn(){
  const data = await setTimeout(function(){
    console.log('setTimeout') 
    return 'data'
  },1000)
  console.log('data',data) // Timeout {} 对象
}
console.log('async',asyncFn()) // Promise { <pending> }

但这两者,实在常常混用,罕见的就是readFile函数的做法啦

看懂以上的,才人人出一道题看看能不能懂;

async function asynFn(){ 
  await Promise.resolve('aaa')
  const data = {
    b:'bb',
    c:function(){ return this.b }
  }
  return data  //return 作为参数通报给then then的chain链也是经由过程return参数来不停通报给背面的then
}
var cball = asynFn()
cball.then(function(data){
  console.log('data:',data)
})

另有一种异步编程的语法糖: * & yield
跟async基础一样,不在本文议论的重点。有兴致自行google啦

参考资料:
async 函数的寄义和用法
Promise 对象

    原文作者:小熊前端
    原文地址: https://segmentfault.com/a/1190000013263119
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞