前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用 Promise 实现任务流的自动重试

利用 Promise 实现任务流的自动重试

作者头像
libo1106
发布2018-08-08 16:49:55
1.1K0
发布2018-08-08 16:49:55
举报
文章被收录于专栏:Web 开发Web 开发

微信小程序不支持 HTTP 的 cookie ,其会话机制是通过开发自己维护一个 session_id 在小程序的本地存储中,每次调用 wx.request 的时候都带上这个 session_id 来实现的会话机制。

那么,有会话机制,就会存在会话失效、更新等等问题。

传统的 HTTP cookie-session 机制,当会话失效的时候,可以在 HTTP 的返回头里面通过 setcookie 来静默返回一个新的 session_id ,小程序就比较麻烦。

传统的实现方案

1.理想的实现情况

代码语言:javascript
复制
let session_id = wx.getStorageSync('session_id');
 
wx.request({
    url: '/api/create',
    header: {session_id},
    method: 'POST',
    data: 'hello world',
    success: (resp) => {
        let {id} = resp.data;
        // 创建成功后,跳转去目标页面
        wx.navigateTo({url: `/article?id=${id}`})
    }
})

2.为了容错,我们会添加返回判断,但错误的时候,再调用一次

代码语言:javascript
复制
// 调用创建接口
function create() {
 
    let session_id = wx.getStorageSync('session_id');
 
    wx.request({
        url: '/api/create',
        header: {session_id},
        method: 'POST',
        data: 'hello world',
        success: (resp) => {
    
            let {status, data} = resp;
    
            if (status === 'session_id error') {
                // 与后端通信,重新下发并更新本地存储中的 session_id
                // 然后再重新自行一次创建行为
                updateSession().then(create);
            } else {
                let {id} = resp.data;
 
                // 创建成功后,跳转去目标页面
                wx.navigateTo({url: `/article?id=${id}`})
            }
        }
    })
}

上面这种方式,在接口的返回值中做一次判断,然后再执行一次,好像就解决问题了。

但如果我们业务的接口非常多,返回判断是不是要添加很多次呢?

基于 Promise 的任务流自动重试

首先,我们先封装一个专门用来发请求的函数,并且全局套上一个会话异常的逻辑

/util/request.js

代码语言:javascript
复制
// 通用请求函数
export function request (obj) {
 
    let session_id = wx.getStorageSync('session_id');
 
    return new Promise((resolve, reject) => {
 
        obj.header = {session_id};
 
        obj.success = (resp) => {
            resp.reqObj = obj;
            resolve(resp);
        }
 
        obj.fail = (resp) => {
            resp.reqObj = obj;
            reject(resp);
        }
 
        // 发出请求
        wx.request(obj);
 
    }).then(session_error)
 
}
 
// 会话异常处理
export function session_error (resp) {
 
    let {status} = resp.data;
 
    // 如果 session_id 没问题,交给后续流程处理
    if (static !== 'session_id error') {
        return resp;
    }
 
    // 如果 session_id 有问题
    return new Promise((resolve, reject) => {
        // 更新 session_id 
        updateSession().then(() => {
            // 重试之前的请求,并继续原先的流程
            request(resp.reqObj).then(resolve);
        });
    })
 
}

然后,我们的业务逻辑,可以简化为

代码语言:javascript
复制
import { request } from 'util/request';
 
// 请求接口
request({
    url: '/api/create',
    data: 'hello world',
    method: 'POST'
}).then((resp) => {
    let {id} = resp.data;
    // 创建成功后,跳转去目标页面
    wx.navigateTo({url: `/article?id=${id}`})
})

不论我们业务有多少次 HTTP 请求要发送,request 函数都能自动帮我们处理好这些通用流程,且支持自动重试自动执行原先断掉的流程。

如果是一些非全局处理的逻辑,也可以改用依赖注入的方式,交给业务代码来决定是否调用。

代码语言:javascript
复制
import { request, session_error } from 'util/request';
 
// 创建文章
request({
    url: '/api/create',
    data: 'hello world',
    method: 'POST'
})
.then(session_error)
.then((resp) => {
    let {id} = resp.data;
    // 创建成功后,跳转去目标页面
    wx.navigateTo({url: `/article?id=${id}`})
})
 
// 拉取公告,不需要会话态
request({
    url: '/api/public_msg',
    method: 'GET'
})
.then((resp) => {
    let msg = resp.data;
    msg && wx.showModal({title: '公告', content: msg});
})

结语

这种基于 Promise 的任务流自动重试,在 Web 应用里面有非常多的使用场景,这里仅仅以小程序的会话态举例。

演示代码为了突出重点,省略了 reject 和重试次数的处理部分,大家记得加上,要不然会出现外层的 catch 不到错误又或者是一直在循环重试。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-02-272,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 传统的实现方案
  • 基于 Promise 的任务流自动重试
  • 结语
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档