經過koa2和Promise.race()構造一個超時取消的ajax。

MDN上說:前端

你可使用AbortController.AbortController()構造函數建立一個新的AbortController對象。 使用AbortSignal 對象完成與DOM請求的通訊。

對於瀏覽器的兼容性有很高的要求,chrome在66版本以上, firefox在57以上,因爲遇到了這樣的需求,因此用傳統的XHR實現了一下這個功能。chrome

服務端使用koa2:瀏覽器

/**
 * @vividw
 * 2019.1.10
 */
const Koa = require('koa');
const app = new Koa();
const Router = require('koa-router');
const router = new Router();
const { resolve } = require('path');
const koaStatic = require('koa-static');
const cors = require('@koa/cors');

const sleep = (count) => new Promise(resolve => {
    setTimeout(resolve, count);
});

// router.get('/', async (ctx, next) => {
//     ctx.body = 'Hello,Wolrd!';
//
//     await next();
// });

router.get('/data', async (ctx, next) => {
    await sleep(3000);
    ctx.body = {
        data: '12345'
    }

    await next();
});

app
    .use(cors())
    .use(koaStatic(resolve(__dirname + '/')))
    .use(router.routes())
    .use(router.allowedMethods());

app.listen(3000, () => {
    console.log('App running!');
});

重要的點在於不能直接使用setTimeout(ctx.body = '12345' ,3000);這樣返回給前端會直接報錯。app

前端的代碼:cors

const ownFetch = (count) => new Promise((resolve,reject) => {
            const xhr = new XMLHttpRequest();

            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    if(xhr.status == 200){
                        resolve(xhr);
                    }
                 }
            }
            xhr.timeout = count;
            xhr.open('get', 'http://localhost:3000/data', true);
            xhr.send();
        })
        window.onload = () => {
            const timeout = (count) => new Promise((resolve, reject) => {
                setTimeout(() => {
                    reject('failed');
                }, count);
            });
            (async () => {
                ownFetch(2000);
            })();
        }

要注意xhr.open()的第三個參數設置成true將AJAX請求設置爲異步,而後因爲超時會取消請求,因此這裏根本不須要xhr.abort()來顯式的取消請求koa

相關文章
相關標籤/搜索