博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
你好,promise
阅读量:6417 次
发布时间:2019-06-23

本文共 4316 字,大约阅读时间需要 14 分钟。

像结识了一位新朋友一样,最近开始学习了promise。一开始接触到这个名词的时候也在脑海中想,promise是到底是做什么的呢。那么下面跟我一起来认识一下promise把。

首先来了解一下promise的含义

简单来说,promise是一种异步流程的控制手段,比传统的回调函数解决方案更合理和简洁。它解决了传统回调函数方式产生的回调地狱的问题。ES6将其写进了语言标准,统一了语法,原生提供了Promise。

下面我们来看一个简单的例子:

有这么一个场景,想做一道菜:首先要去买菜,买完菜之后才能洗菜,洗完菜之后才能切菜,切完之后才能炒菜,转换成js如下:

function A(callback){    setTimeout(function(){        callback("菜买好了");    }, 1000);}function B(callback){     setTimeout(function(){          callback("菜洗好了");     }, 2000);}function C(callback){     setTimeout(function(){          callback("菜切好了");     }, 3000);} function D(callback){     setTimeout(function(){          callback("菜炒好了");     }, 3000);} 复制代码
  • 传统的回调函数方式是
A(function(res){     console.log(res);     B(function(res){          console.log(res);          C(function(res){                console.log(res);                C(function(res){                    console.log(res);                    console.log("菜炒好啦");                });           });     });});复制代码

这就是传说中的回调地狱,实际的场景嵌套的层级可能还更多。这种代码非常不易于理解,而且代码难以维护。 而promise就非常适合这种场景,上面的代码用promise实现

function A() {    return new Promise(function (resolve, reject) {         setTimeout(function(){            resolve("菜买好了");        }, 1000);    });}function B() {    return new Promise(function (resolve, reject) {          setTimeout(function(){               resolve("菜洗好了");          }, 2000);    });}function C() {    return new Promise(function (resolve, reject) {          setTimeout(function(){               resolve("菜切好了");          }, 2000);    });}function D() {    return new Promise(function (resolve, reject) {          setTimeout(function(){               resolve("菜炒好了");          }, 2000);    });}A().then(function(res) {    console.log(res);    return B();}).then(function(res) {    console.log(res);    return C();}).then(function(res) {    console.log(res);    return D();}).then(function(res) {    console.log(res);    console.log("菜炒好了");});复制代码

可见Promise最大的好处是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了。

深入理解promise

Promise对象可以理解为一次将要执行的操作(常常被用于异步操作),使用了 Promise 对象之后可以用一种链式调用的方式来组织代码,让代码更加直观。promise 实现链式调用返回的并不是this而是一个新的promise。

promise(承诺)有三种状态,分别是

  • resolve (成功)
  • reject (失败)
  • pending (等待态)

状态改变: Promise对象的状态改变,只有两种可能: 从pending变为reject。 从pending变为resolve 如果一旦promise成功了就不能失败,相反也是一样的。所以这两种情况只要发生,状态就凝固了,不会再变了,这时就称为resolved(已定型)。

每一个promise的实例上都有一个then方法,then方法中有两个参数,一个参数叫成功的函数 ,一个是失败的函数。 then方法定义:then(fulfilledAHandler, errorHandler),对应着Promise的resolve, reject。

一个promise可以then多次

let p = new Promise((resolve,reject)=>{  resolve('成功');});p.then(data=>{  console.log(data);});p.then(data=>{  console.log(data);})p.then(data => {  console.log(data);});复制代码

promise中只要发生错误,就会执行失败态。如果返回的是一个普通值就会走到写一个then中的成功回调,如果有错误产生会走失败的回调。

  • Promise只有一个参数 叫excutor执行器,默认new时就会调用
let p = new Promise((resolve,reject)=>{   // 默认promise中的executor是同步执行的   resolve('买');});// then方法是异步调用的,事件环p.then((value)=>{ // value成功  console.log(1);},(err)=>{ // err失败});console.log(2);复制代码

执行结果,2 1。

promise可以处理并发任务

promise用promise.all方法做并发调用,当所有Promise 对象都变为完成态或失败态时,回调将被执行。

let fs = require('fs'); // fileSystemfunction read(url) {  return new Promise((resolve, reject) => {    fs.readFile(url, 'utf8', function (err, data) {      if (err) reject(err);      resolve(data);    })  })}Promise.all([read('1.txt'),read('2.txt')]).then((data)=>{   console.log(data); },err=>{   console.log(err); });复制代码

promise.race赛跑,处理多请求只取最快的

Promise.all([read('1.txt'),read('2.txt')]).then((data)=>{   console.log(data); },err=>{   console.log(err); });复制代码

读取哪个文件快,返回哪个文件的结果

Promise.resolve() 返回一个成功的promise

Promise.reject() 返回一个失败的promise

promise.reject('123').then(null,data=>{  console.log(data);});复制代码

最后用es6语法简单实现一下Promise的原理

class Promise {  constructor(executor) {    this.status = 'pending';    this.value = undefined;    this.reason = undefined;    let resolve = value => {      if (this.status ==='pending'){        this.status = 'resolved';        this.value = value;      }    }    let reject = reason => {      if (this.status === 'pending') {        this.status = 'rejected';        this.reason = reason;      }    }    try {      executor(resolve, reject);    } catch (e) {      reject(e);    }  }  then(onFufilled,onRjected){    if(this.status === 'resolved'){      onFufilled(this.value);    }    if(this.status === 'rejected'){      onRjected(this.reason);    }  }}module.exports = Promise复制代码

转载地址:http://omvra.baihongyu.com/

你可能感兴趣的文章
弹窗 组件 封装
查看>>
[Widget] HTML5解决跨域问题
查看>>
Uva 1451
查看>>
python基础一 ------"有序"的字典
查看>>
JS为句柄添加监听函数
查看>>
[导入]WAP编程(性能篇)
查看>>
curl 发送get post请求
查看>>
linux介绍
查看>>
JS 用sort方法排序字符串
查看>>
phpstrom调试神器
查看>>
Windows下磁盘无损重新分配
查看>>
实践:VIM深入研究(20135301 && 20135337)
查看>>
Shell 流程控制
查看>>
mongodb配置
查看>>
多客户端项目的冗余服务器
查看>>
如何把session保存在mysql中?
查看>>
error C2872: “ACCESS_MASK”: 不明确的符号
查看>>
第10周作业
查看>>
hdu 1556 Color the ball (树状数组)
查看>>
POJ 2513 Colored Sticks【欧拉通路】
查看>>