promise的用法

一、promise相关概念

回调方法:就是将一个方法 func2 作为参数传入另一个方法 func1 中,当 func1 执行到某一步或者满足某种条件的时候才执行传入的参数 func2

Promise 是 ES6 引入的异步编程的新解决方案。

Promise 对象三种状态:初始化、成功、失败 pending-进行中、resolved-已完成、rejected-已失败

就好像,你跟你女朋友求婚,她跟你说她要考虑一下,明天才能给你答案,这就是承诺(promise)。同时,这也是一个等待的过程(pending),然后你就等,等到明天你女朋友给你答复,同意(resolved)或者拒绝(rejected),如果同意就准备结婚了,如果不同意就等下次再求婚,哈哈哈。

promise 是用来解决两个问题的:

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

二、promise基本用法

这样构造 promise 实例,然后调用 .then.then.then 的编写代码方式,就是 promise。

let p = new Promise((resolve, reject) => {      //    调用了Promise构造函数
  // 做一些事情
  // 然后在某些条件下resolve,或者reject
  if (/* 条件随便写^_^ */) {
    resolve()
  } else {
    reject()
  }
})

p.then(() => {                                 //    调用了promise实例的.then方法
    // 如果p的状态被resolve了,就进入这里
}, () => {
    // 如果p的状态被reject
})

三、声明一个promise对象

new Promise((resolve, reject) => {     // 这两个方法主要是用来修改状态的
    console.log("开始求婚。")
    console.log("。。。。。")
    console.log("考虑一下。")
    setTimeout(() => {
        if (isHandsome || isRich) { // 当我们调用 resolve 函数的时候,Promise 的状态就变成 resolved
            resolve('我同意!')
        } else { // 当我们调用 reject 函数的时候,Promise 的状态就变成 reject
            reject("拒绝:我们八字不合")
        }
    }, 2000)
})
// 如果一个 promise 已经被兑现(resolved)或被拒绝(rejected),那么我们也可以说它处于已敲定(settled)状态。

四、Promise.prototype.then 方法

已成功 resolved 的回调和已失败 rejected 的回调

// 调用 Promise 对象的then方法,两个参数为函数
p.then(function(value){ // 成功
     console.log(value);
}, function(season){ // 失败
     console.log(season);
});

五、Promise.prototype.catch 方法

catch() 的作用是捕获 Promise 的错误

其实它和 then 的第二个参数一样,用来指定 reject 的回调,用法是这样:

在执行 resolve 的回调(也就是上面 then 中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死 js,而是会进到这个 catch 方法中。请看下面的代码:

promise.then(
    () => { console.log('this is success callback') }
).catch(
    (err) => { console.log(err) }
)

效果和写在 then 的第二个参数里面一样。不过它还有另外一个作用:在执行 resolve 的回调(也就是上面 then 中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死 js ,而是会进到这个 catch 方法中。请看下面的代码:

getNumber()
.then(function(data){
    console.log('resolved');
    console.log(data);
    console.log(somedata);  //此处的somedata未定义
})
.catch(function(reason){
    console.log('rejected');
    console.log(reason);
});

六、Promise.all() 方法

  • 有了 all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据。
  • 「谁跑的慢,以谁为准执行回调」
  • Promise 的 all 方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调
Promise
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
    console.log(results);
});

Promise.all 手撕代码题:

const myPromiseAll =(arr)=>{
     let result = [];
     return new Peomise ((resolve,reject)=>{
         for (let i=0;i<arr.length;i++){
             arr[i].then(data=>{
                 result[i] = data;
                 if(result.length === arr.length)//所有的都成功才执行成功的回调
                 {
                     resolve(result)
                   }//这里可以用计数器更好点
             },reject)//有一个失败则执行失败的回调
         }
     })
}

七、Promise.race() 方法

  • 「谁跑的快,以谁为准执行回调」
  • 1 秒后 runAsync1 已经执行完了,此时then里面的就执行了
  • 在 then 里面的回调开始执行时,runAsync2() 和 runAsync3() 并没有停止,仍旧再执行。
  • 于是再过 1 秒后,输出了他们结束的标志。
//请求某个图片资源
function requestImg(){
    var p = new Promise(function(resolve, reject){
        var img = new Image();
        img.onload = function(){
            resolve(img);
        }
        img.src = 'xxxxxx';
    });
    return p;
}

//延时函数,用于给请求计时
function timeout(){
    var p = new Promise(function(resolve, reject){
        setTimeout(function(){
            reject('图片请求超时');
        }, 5000);
    });
    return p;
}

Promise
.race([requestImg(), timeout()])
.then(function(results){
    console.log(results);
})
.catch(function(reason){
    console.log(reason);
});

八、Promise.any() 方法

any() 方法还接受一组 promise 作为参数,并将它们打包到新的 promise 对象中。只要一个参数实例处于成功状态,新的 promise 就处于成功状态。参数实例均处于拒绝状态。新承诺处于拒绝状态。

Promise.any(promises).then(
    (first) => {
    // Any of the promises was fulfilled.
    },(error) => {
    // All of the promises were rejected.
    }
);

Promise.any手撕代码题:

function myPromiseAny(arr) {
    if (!Array.isArray(arr)) {
        throw new Error('arguments must be a array');
    }
    let rejectCount = 0;
    return new Promise((resolve, reject) => {
        for (let i = 0; i < arr.length; i++) {
            arr[i].then(data => {
                resolve(data);
            }, () => {
                rejectCount++;
                if (rejectCount === arr.length) {
                    reject(new AggregateError('All promises were rejected'))
                }
            });
        }
    })
}

九、Promise.prototype.finally() 方法

finally 方法用于指定无论 Promise 对象的最终状态如何,都将执行 finally。Finally 不接受参数。Finally 独立于先前的执行状态,不依赖于先前的运行结果。

    const promise4 = new Promise((resolve, reject) => {
      console.log(x + 1);
      });
    promise4
      .then(() => {
        console.log("你好");}
        ).catch((err) => {
        console.log(err);}
        ).finally(() => {
        console.log("finally");});// finally

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值