函数(四)生成器和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);
  }
})()
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354

推荐阅读更多精彩内容