欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【es6】promise

程序员文章站 2022-05-01 16:43:20
一、什么是promise?我们用promise解决什么样的问题 promise是异步编程的一种解决方案:从语法上来说,Promise是一个对象,从他可以获取异步操作的信息;从本意上讲,它是承诺,它承诺过一段时间会给你一个答复。Promise有三种状态:pending(等待态)、fulfiled(成功 ......

一、什么是promise?我们用promise解决什么样的问题

  promise是异步编程的一种解决方案:从语法上来说,promise是一个对象,从他可以获取异步操作的信息;从本意上讲,它是承诺,它承诺过一段时间会给你一个答复。promise有三种状态:pending(等待态)、fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。

  promise常常用来解决两个问题:

  • 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
  • promise可以支持多个并发的请求,获取并发请求中的数据
  • 这个promise可以解决异步的问题,本身不能说promise是异步的

二、promise 用法大全

  1、基础用法

  

let p = new promise( (resolve, reject) => {
    console.log('我刚刚进来')
    settimeout(() => {
        console.log('执行成功');
        resolve('我是成功');
        reject('我是失败');
    }, 2000);
    console.log('我在函数的末尾')
});


p.then( (data) => {
    console.log(data)
})

// 执行结果

// 我刚刚进来
// 我在函数的末尾
// 执行成功
// 我是成功

 
promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数:
  • resolve :异步操作执行成功后的回调函数
  • reject:异步操作执行失败后的回调函数

  2、链式编程

p.then( (data) => {
    console.log(data);
    return '我是第一个then'
})
.then( (data) => {
    console.log(data);
    return () => {
        console.log('我是第二个then的方法')
    }
})
.then( (fun) => {
    fun();
})

所以,从表面上看,promise只是能够简化层层回调的写法,而实质上,promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。所以使用promise的正确场景是这样的:

  3、reject的用法(失败状态)

let p2 = new promise( (resolve, reject) => {
    settimeout(() => {
        let num = math.ceil(math.random() * 10);
        if (num > 5 ) {
            resolve(`${num}大于5,成功了`)
        } else {
            reject(`${num}小于5,失败了`)
        }
    }, 2000)
});

p2.then((data) => {
    console.log('resolve', data)
}, (err) => {
    console.log('reject', err)
});
// 执行结果
// reject 1小于5,失败了
// resolve 8大于5,成功了

用来处理失败的情况

  4、catch的用法

  我们知道promise对象除了then方法,还有一个catch方法,它是做什么用的呢?其实它和then的第二个参数一样,用来指定reject的回调。用法是这样:

p.then((data) => {
    console.log('resolved',data);
    console.log(err); //此处的err未定义
})
.catch((err) => {
    console.log('rejected',err);
});

  catch在promise中的任何一步出现异常都不会卡死js的运行,而是会进入到这个catch中。catch类似于 try - catch;

  5.all 的用法

  

let promise1 = new promise(function(resolve, reject){
    settimeout(() => {
        let num = math.ceil(math.random() * 10);
        if (1) {
            resolve(`${num}大于5,promise1成功了`)
        } else {
            reject(`${num}小于5,promise1失败了`)
        }
    }, 2100)
})
let promise2 = new promise(function(resolve, reject){
    settimeout(() => {
        let num = math.ceil(math.random() * 10);
        if (1 ) {
            resolve(`${num}大于5,promise2成功了`)
        } else {
            reject(`${num}小于5,promise2失败了`)
        }
    }, 2200)
})
let promise3 = new promise(function(resolve, reject){
    settimeout(() => {
        let num = math.ceil(math.random() * 10);
        if (1 ) {
            resolve({'ccc': `${num}大于5,promise3成功了`})
        } else {
            reject(`${num}小于5,promise3失败了`)
        }
    }, 2300)
})

let pall = promise.all([promise1, promise2, promise3])

pall.then((data) => {
    console.log(data, '成功')
}, (err) =>{
  console.log(err, '失败')
})
// 执行结果
// [ '4大于5,promise1成功了',
//   '8大于5,promise2成功了',
//   { ccc: '9大于5,promise3成功了' } ] '成功'

  all方法: 谁跑的慢,就以谁为执行准执行回调。all接收一个数组参数,里面的值最终都返回到promise对象中。

  有了all方法,就可以一次执行多个异步操作,并且可以统一处理返回结果。例:在打开一个页面是可以统一加载一些配置信息,比如下拉框选项等资源。

  6、race用法

  

let p2 = new promise( (resolve, reject) => {
    settimeout(() => {
        let num = math.ceil(math.random() * 10);
        if (num > 5 ) {
            resolve(`${num}大于5,成功了`)
        } else {
            reject(`${num}小于5,失败了`)
        }
    }, 5000)
});
let promise3 = new promise(function(resolve, reject){
    settimeout(() => {
        let num = math.ceil(math.random() * 10);
        if (1 ) {
            resolve({'ccc': `我执行的快,就我了`})
        } else {
            reject(`${num}小于5,promise3失败了`)
        }
    }, 2300)
})
 promise.race([p2, promise3]).then((data) =>{
        console.log(data);
    }).catch((err) => {
        console.log(err);
    });
// { ccc: '我执行的快,就我了' }

 

  reac用来处理加载超时的情况。