函数(四)生成器和promise

1 生成器函数

定义和使用生成器

生成器函数能生成一组值的序列。显式地向生成器请求一个新的值,随后生成器响应一个新生成的值,或者告诉我们它之后不会再生成新的值。
可以使用while迭代生成器生成的值的序列,也可以使用for-of语法糖。

function *DiningCar(){
  yield '花生';
  yield '瓜子';
  yield '八宝粥';
}

const carIt=DiningCar();
let item;
while(!(item=carIt.next()).done){
  console.log(item.value);
}

for(let item of DiningCar()){
  console.log(item);
}

双向通信

我们通过yield语句从生成器中返回值,再使用迭代器的next方法把值传回生成器。

function *DiningCar(user_name){
  let count_peanuts=yield '花生';
  let count_seed=yield '瓜子';
  let count_congee=yield '八宝粥';
  console.log('顾客姓名:'+user_name);
  console.log('花生:'+count_peanuts);
  console.log('瓜子:'+count_seed);
  console.log('八宝粥:'+count_congee);
}
const carIt=DiningCar('bro bear');
carIt.next();//返回'花生'
carIt.next(1);
carIt.next(2);
carIt.next(3);

向生成器抛出异常

迭代器除了next方法,还具有抛出一个异常的方法。

function *DiningCar(){
  try{
    yield '花生';
    yield '瓜子';
    yield '八宝粥';
  }
  catch(e){
    console.log('交易失败:'+e);
  }
}
const carIt=DiningCar();
console.log(carIt.next());
carIt.throw('no enough money.');

2 promise

promise对象是对我们现在尚未得到但将来会得到的值的占位符。如果我们兑现了承诺,结果会得到一个值。如果发生了问题,结果则是一个错误。

显式接受/拒绝promise

var promise=new Promise((resolve,reject)=>{
  resolve('23:00');
  //reject('2:00');
})
promise.then(time=>{
  console.log('sleep at '+time);
},time=>{
  console.log('sleep at '+time);
});

异常隐式拒绝promise

var promise=new Promise((resolve,reject)=>{
  sheep++;
})
promise.then(time=>{
  console.log('sleep at '+time);
}).catch(()=>{
  console.log('fail to sleep');
})

创建一个promise实例

promise的一个最佳例子是从服务器获取数据。我们要承诺最终会拿到数据,但总有可能发生错误。

function getJSON(url){
  return new Promise((resolve,reject)=>{
    const request=new XMLHttpRequest();
    request.open('GET',url);
    request.onload=()=>{
      try{
        if(this.status===200){
          //解析json时可能发生异常
          resolve(JSON.parse(this.response));
        }
        else{
          //服务器响应了其他代码
          reject(this.status+' '+this.statusText);
        }
      }
      catch(e){
        reject(e.message);
      }
    }
    request.onerror=()=>{
      //和服务器通信异常
      reject(this.status+' '+this.statusText);
    };
    request.send();
  });
}

getJSON('peanut.json').then(data=>{
  console.log('we have peanuts!');
}).catch(e=>{
  console.log('we have no peanuts!');
})

链式调用

处理多个有先后顺序、相互依赖的异步任务。

getJSON('peanuts.json')
  .then(getJSON('seeds.json'))
  .then(getJSON('congee.json'))
  .catch(error=>console.log('we have not enough food!'));

等待多个promise

处理多个独立的异步任务。
Promise.all方法接收一个Promise数组,并创建一个新的promise对象。当所有的promise均成功时,该promise为成功状态。反之,若其中任意一promise失败,则该promise为失败状态。

Promise.all([getJSON('peanuts.json'),
  getJSON('seeds.json'),
  getJSON('congee.json')
]).then(results=>{
  results.forEach(item=>console.log('we have'+item));
}).catch(error=>console.log('交易失败!'+error));

promise竞赛

Promise.race方法接收一个Promise数组,并创建一个新的promise对象。当某一个promise被处理或被拒绝时,该promise同样会被处理或被拒绝。

Promise.race([getJSON('peanuts.json'),
  getJSON('seeds.json'),
  getJSON('congee.json')
]).then(results=>{
  results.forEach(item=>console.log('we have'+item));
}).catch(error=>console.log('交易失败!'+error));

3 生成器和promise相结合

不明觉厉

(async ()=>{
  try{
    const peanuts=await getJSON('peanuts.json');
    const seeds=await getJSON('seed.json');
    const congee=await getJSON('congee.json');
  }catch(e){
    console.log('Error:'+e);
  }
})()

你可能感兴趣的:(函数(四)生成器和promise)