promise常见的使用案例

promise在Node.js中还是比较常见的,本文主要总结三个常用的promise使用案例。

目录

一、promise 请求超时处理

二、promise 三次重试

三、promise并发请求并控制请求数目


 

一、promise 请求超时处理

需求:在微服务中发送一个请求,如果三秒钟还没有收到结果,我们就认为失败。

这里面是使用的是Promise.race。

Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。并行执行

const p = Promise.race([p1, p2, p3]);

上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

const p = Promise.race([
    getUrl('/resource-that-may-take-a-while'),
    new Promise(function (resolve, reject) {
      setTimeout(() => reject(new Error('request timeout')), 5000)
    })
  ]);
  
  p.then(console.log)
  .catch(console.error);

二、promise 三次重试

需求:用promise实现一个可以指定重试次数的方法,如果重试次数等于指定的重试测试时,还没有成功,则认为失败。

var execCount = 3;

var getData = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            execCount--;
            console.error("execCount", execCount);
            if (execCount < 0) {
                resolve("success");
            } else {
                reject("error");
            }
        }, 2000);
    });
}


function retryData(getData, times, delay) {
    return new Promise((resolve, reject) => {
        function attempt() {
            getData().then(resolve).catch((erro) => {
                console.log(`还有 ${times} 次尝试`);
                if (0 == times) {
                    reject(erro);
                } else {
                    times--;
                    setTimeout(() => {
                        attempt();
                    }, delay * 1000);
                }
            })
        }
        attempt();
    })
}

retryData(getData, 3, 3).then((res) => {
    console.error("执行成功", res);
}).catch((err) => {
    console.error(err)
})

execCount 2
还有 3 次尝试
execCount 1
还有 2 次尝试
execCount 0
还有 1 次尝试
execCount -1
执行成功 success

三、promise并发请求并控制请求数目

有 n 个图片资源的 url,已经存储在数组 urls 中(即urls = [‘http://example.com/1.jpg’, …., ‘http://example.com/8.jpg’]),而且已经有一个函数 function loadImg,输入一个 url 链接,返回一个 Promise,该 Promise 在图片下载完成的时候 resolve,下载失败则 reject。

但是我们要求,任意时刻,同时下载的链接数量不可以超过 3 个。

var urls = [1, 2, 3, 4, 5, 6, 7, 8, 9];

function loadImg(url) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(`第 ${url} 张图片加载完成`);
            resolve("success");
        }, 2 * 1000);
    })
};

// 计数器
var count = 0;
// 全局锁
var lock = [];
var l = urls.length;

// 阻塞函数
function block() {
    let _resolve;
    return new Promise((resolve, reject) => {
        _resolve = resolve;
        // resolve不执行,将其推入lock数组;
        lock.push(_resolve);
    });
}
// 叫号机
function next() {
    lock.length && lock.shift()();
}

async function reuqest() {
    if (count >= 3) {
        //超过限制利用await和promise进行阻塞;
        await block();
    }
    if (urls.length > 0) {
        console.log(count);
        count++
        await loadImg(urls.shift());
        count--;
        next();
    }
}

for (let i = 0; i < l; i++) {
    reuqest();
}

这里面的思想 我们主要使用async和await 来形成阻塞函数,当我们的请求书大于3个的时候,我们把promise中的resolve保存到数组里面,先不执行。当有图片加载出来后,我们在继续执行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值