26:promise+Generator+Async 的使用

Promise

解决的问题:回调地狱

Promise 规范:

promise 有三种状态,等待(pending)、已完成(fulfilled/resolved)、已拒绝(rejected)

.Promise 的状态只能从“等待”转到“完成”或者“拒绝”,不能逆向转换,同时“完成”和 “拒绝”也不能相互转换.

promise 必须提供一个 then 方法以访问其当前值、终值和据因。promise.then(resolve, reject),resolve 和 reject 都是可选参数。如果 resolve 或 reject 不是函数,其必须被忽略.

then 方法必须返回一个 promise 对象.

使用:

实例化 promise 对象需要传入函数(包含两个参数),resolve 和 reject,内部确定状态.resolve 和 reject 函数可以传入参数在回调函数中使用.

resolve 和 reject 都是函数,传入的参数在 then 的回调函数中接收.

var promise = new Promise(function(resolve, reject) { 

  setTimeout(function(){ 

    resolve('好哈哈哈哈'); 

  }); 

}); 

promise.then(function(val){ 

  console.log(val) 

})

then 接收两个函数,分别对应 resolve 和 reject 状态的回调,函数中接收实例化时传入的参数.

promise.then(val=>{ 

  //resolved 

},reason=>{ 

  //rejected 

})

catch 相当于.then(null, rejection)

当 then 中没有传入 rejection 时,错误会冒泡进入 catch 函数中,若传入了 rejection,则错误会被 rejection 捕获,而且不会进入 catch.此外,then 中的回调函数中发生的错误只会在下一级的 then 中被捕获,不会影响该 promise 的状态.

new Promise((resolve,reject)=>{ 

  throw new Error('错误') 

}).then(null,(err)=>{ 

  console.log(err,1);//此处捕获 

}).catch((err)=>{ 

  console.log(err,2); 

}); 

// 对比 

new Promise((resolve,reject)=>{ 

  throw new Error('错误') 

}).then(null,null).catch((err)=>{ 

  console.log(err,2);//此处捕获 

}); 

// 错误示例 

new Promise((resolve,reject)=>{ 

  resolve('正常'); 

}).then((val)=>{ 

  throw new Error('回调函数中错误') 

},(err)=>{ 

  console.log(err,1); 

}).then(null,(err)=>{ 

  console.log(err,2);//此处捕获,也可用 catch 

}); 

两者不等价的情况:

此时,catch 捕获的并不是 p1 的错误,而是 p2 的错误,

p1().then(res=>{ 

  return p2()//p2 返回一个 promise 对象 

}).catch(err=> console.log(err)) 

一个错误捕获的错误用例:

该函数调用中即使发生了错误依然会进入then 中的resolve 的回调函数,因为函数 p1中实例化 promise 对象时已经调用了 catch,若发生错误会进入 catch 中,此时会返回一个新的 promise,因此即使发生错误依然会进入 p1 函数的 then 链中的 resolve 回调函数.

function p1(val){ 

  return new Promise((resolve,reject)=>{ 

    if(val){ 

      var len = val.length;//传入 null 会发生错误,进入 catch 捕获错 

      resolve(len); 

    }else{ 

      reject(); 

    }

}).catch((err)=>{ 

  console.log(err) 

})

};

p1(null).then((len)=>{ 

  console.log(len,'resolved'); 

},()=>{ 

  console.log('rejected'); 

}).catch((err)=>{ 

  console.log(err,'catch'); 

})

Promise 回调链:

promise 能够在回调函数里面使用 return 和 throw, 所以在 then 中可以 return 出一个 promise 对象或其他值,也可以 throw 出一个错误对象,但如果没有 return,将默认返回 undefined,那么后面的 then 中的回调参数接收到的将是 undefined.

function p1(val){ 

  return new Promise((resolve,reject)=>{ 

      val==1?resolve(1):reject() 

  })

};

function p2(val){ 

  return new Promise((resolve,reject)=>{ 

      val==2?resolve(2):reject(); 

  })

};

let promimse = new Promise(function(resolve,reject){ 

  resolve(1) 

})

.then(function(data1) { 

  return p1(data1)//如果去掉 return,则返回 undefined 而不是 p1 的返回值,会导致报错 

})

.then(function(data2){ 

  return p2(data2+1) 

})

.then(res=>console.log(res)) 

Generator 函数:

generator 函数使用:

1、分段执行,可以暂停

2、可以控制阶段和每个阶段的返回值

3、可以知道是否执行到结尾

function* g() { 

  var o = 1; 

  yield o++; 

  yield o++; 

}

var gen = g(); 

console.log(gen.next()); // Object {value: 1, done: false} 

var xxx = g(); 

console.log(gen.next()); // Object {value: 2, done: false} 

console.log(xxx.next()); // Object {value: 1, done: false} 

console.log(gen.next()); // Object {value: undefined, done: true} 

generator 和异步控制:

利用 Generator 函数的暂停执行的效果,可以把异步操作写在 yield 语句里面,等到调用 next 方法时再往后执行。这实际上等同于不需要写回调函数了,因为异步操作的后续操作可以放在 yield 语句下面,反正要等到调用 next 方法时再执行。所以,Generator 函数的一个重要实际意义就是用来处理异步操作,改写回调函数。

async 和异步:

用法:

async 表示这是一个 async 函数,await 只能用在这个函数里面。

await 表示在这里等待异步操作返回结果,再继续执行。

await 后一般是一个 promise 对象

示例:async 用于定义一个异步函数,该函数返回一个 Promise。

如果 async 函数返回的是一个同步的值,这个值将被包装成一个理解 resolve 的 Promise, 等同于 return Promise.resolve(value)。

await 用于一个异步操作之前,表示要“等待”这个异步操作的返回值。await 也可以用于一个同步的值。

let timer = async function timer(){ 

return new Promise((resolve,reject) => { 

setTimeout(() => { 

resolve('500'); 

},500); 

}); 

}

timer().then(result => { 

console.log(result); //500 

}).catch(err => { 

console.log(err.message); 

}); 

//返回一个同步的值 

let sayHi = async function sayHi(){ 

let hi = await 'hello world'; 

return hi; //等同于 return Promise.resolve(hi); 

}

sayHi().then(result => { 

console.log(result); 

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

推荐阅读更多精彩内容