es6异步处理方法之Promise对象

Promise对象

含义

Promise 是异步编程的一种解决方案,可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数,同时使得控制异步操作更加容易。

语法

实例化一个Promise对象,接受一个函数作为参数,该函数有两个回调函数作为参数,分别是resolve()reject(),异步操作成功则回调resovle()返回成功结果,使用Promise.then()来接受成功结果,失败则回调reject()返回失败结果,使用Promise.catch()来接受失败结果

//第一步:Promise实例化,接受一个函数作为参数
const p = new Promise((resolve,reject)=>{
  //第二步:该参数有两个回调函数参数resolve以及reject

  /* to do something... */

 //第三步:异步操作成功则返回resolve函数,失败则返回rejecth函数
  if (/* 异步操作成功 */){
    resolve(/* 异步操作结果 */);
  } else {
    reject(/* 异步操作结果 */);
  }
})

p.then(res=>{
  //接受异步操作成功结果
}).catch(error=>{
  //接受异步操作失败结果
})

  • demo
function studyPromise(value){
  const p = new Promise((resolve,reject)=>{
    if(value){
      resolve('success');
    }else{
      reject('fail');
    }
  })
  return p;
}

studyPromise().then(res=>{
  console.log(res);//不打印
}).catch(error=>{
  console.log(error);//fail
})

studyPromise(true).then(res=>{
  console.log(res);//success
}).catch(error=>{
  console.log(error);//不打印
})

因为resolve()和reject()在本轮事件中最后执行,因此resolve或reject后面存在代码会先执行

new Promise((resolve, reject) => {
  resolve(1);
  const  value = 2;
  console.log(value);
}).then(res => {
  console.log(res);
});

结果是会先打印2再打印1,因此在resolve或reject前加上return

new Promise((resolve,reject)=>{
  if (/* 异步操作成功 */){
   return resolve(/* 异步操作结果 */);
  } else {
   return reject(/* 异步操作结果 */);
  }
})

Promise.then()

作用

当promise对象返回resolve状态时接受结果

  • demo
const p = new Promise((resolve,reject)=>{
  return resolve('I am resolve')
})

p.then(res=>console.log(res));//I am resolve

采用链式写法可以使用多个then()

const p = new Promise((resolve,reject)=>{});
p.then().then().then().then()....catch();

采用链式的then,若无返回值时,会依次按顺序执行方法

const p = new Promise((resolve,reject)=>{
  setTimeout(()=>resolve(1),3000);
});
p.then(res=>console.log(res))
.then(()=>console.log(2))
.then(()=>console.log(3))
.then(()=>console.log(4))
.catch();
//3秒后依次输出1,2,3,4

有返回值时后一个then方法接受前一个的返回值

const p = new Promise((resolve,reject)=>{
  setTimeout(()=>resolve(1),3000);
});
p.then(res=>console.log(res))
.then(()=>{
 console.log(2)
 return 3
})
.then(res=>{
  console.log(res);
  return 4
})
.then(res=>console.log(res))
.catch();

结果:3秒后打印1接着再打印2,3,4

当then返回值是一个promise对象时,要等promise对象返回异步操作结果,如果结果为resolve才能执行下一个then,若为reject中断执行then,从而执行catch()

const p = new Promise((resolve,reject)=>{
  setTimeout(()=>resolve(1),3000);
});
p.then(res=>{
  console.log(res);
  return new Promise((resolve,reject)=>{
    setTimeout(()=>resolve(2),2000);
  });
})
.then((res)=>{
 console.log(res)
 return new Promise((resolve,reject)=>{
    setTimeout(()=>reject(new Error('fail')),1000);
  });
})
.then(res=>{
  console.log(4);
})
.then(res=>console.log(res))
.catch(error=>console.log(error));

结果:3秒后打印1,接着2秒后打印2,再1秒后打印Error:fail,4不打印

Promise.catch()

作用

当promise对象返回reject状态抛出错误时接受结果

  • demo
const p = new Promise((resolve,reject)=>{
  return reject('I am reject')
})
const p1 = new Promise((resolve,reject)=>{
  throw new Error('I am error');
})

p.catch(error=>console.log(error));//I am reject
p1.catch(error=>console.log(error));//Error: I am error

可以把错误的结果放进reject()

// 写法一
const promise = new Promise(function(resolve, reject) {
  try {
    throw new Error('test');
  } catch(e) {
    reject(e);
  }
});
promise.catch(function(error) {
  console.log(error);
});

// 写法二
const promise = new Promise(function(resolve, reject) {
  reject(new Error('test'));
});
promise.catch(function(error) {
  console.log(error);
});

因此reject方法的作用,等同于抛出错误

promise.all()

作用

将多个 Promise 实例,包装成一个新的 Promise 实例,既可以同时执行多个promise实例后操作下一步步骤

语法

Promise.all()方法接受一个数组作为参数,数组成员为promise实例,若不是则使用Promise.resolve()转化成Promise实例。

Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例

Promise.all([/*promise实例1*/,/*promise实例2*/,/*promise实例3*/...])
.then(res=>res)
.catch(error=>error)

所有promise实例都返回resolve结果时,使用promise.all().then()接受结果,结果为一个数组,每个数组成员对应每个promise实例的resolve结果

const p = new Promise((resolve,reject)=>{
  setTimeout(()=>{resolve(1)},1000)
})

const p1 = ()=>{
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{resolve(2)},2000)
  })
}

const p2 = Promise.resolve(3);

Promise.all([p,p1(),p2]).then(res=>console.log(res));//[1,2,3]

所有promise实例当中有一个返回reject结果时,使用promise.all().catch()接受结果,结果为第一个有返回reject的结果

const p = new Promise((resolve,reject)=>{
  setTimeout(()=>{resolve(1)},1000)
})

const p1 = ()=>{
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{reject(2)},2000)
  })
}

const  p2= ()=>{
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{reject(3)},2000)
  })
}
Promise.all([p,p1(),p2()]).catch(res=>console.log(res));//2

但promise实例出现reject时想执行Promise.all().then()需要在reject的promise中做自定义catch方法处理

const p1 = new Promise((resolve, reject) => {
  return resolve('hello');
})

const p2 = new Promise((resolve, reject) => {
      throw 'world'
}).catch(error =>error);

Promise.all([p1, p2]).then(res => {
    console.log(res);// ["hello", "world"]
})

reject的promise一定要严格按照这样格式来做

new Promise((resolve, reject) => {
      throw ... //data数据
      //或 throw new Error(...)
}).catch(error => error);

Promise.resolve()与Promise.reject()

Promise.resolve()与Promise.reject()接受一个参数

如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved,Promise.reject方法返回一个新的 Promise 对象,状态为reject

const p = Promise.resolve('Hello');
p.then(res=>console.log(res));//Hello

const p1 = Promise.reject('World');
p1.catch(error=>console.log(error));//World

Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。

所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve()方法

const p = Promise.resolve();

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

推荐阅读更多精彩内容

  • Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函...
    neromous阅读 8,556评论 1 56
  • 前言 本文旨在简单讲解一下javascript中的Promise对象的概念,特性与简单的使用方法。并在文末会附上一...
    _暮雨清秋_阅读 2,149评论 0 3
  • 编后吐槽:写的快花眼,很详细,耐心看必受益匪浅 JavaScript的执行环境是「单线程」的。所谓单线程,是指JS...
    果汁凉茶丶阅读 4,567评论 8 27
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 8,603评论 0 29
  • JavaScript里通常不建议阻塞主程序,尤其是一些代价比较昂贵的操作,如查找数据库,下载文件等操作,应该用异步...
    张歆琳阅读 2,700评论 0 12