2016-05-11 8 views
1

Как я могу завершить запрос в koa.js, используя другой запрос. Допустим, я поддерживаю активные контексты запросов в объекте. Предположим, что запрос A запущен и занимает много времени. Как я могу сделать другой запрос, который сообщает запросу A завершить.Koa.js abort running request

var requests = {}; 

// middleware to track requests 
app.use(function*(next) { 
    var reqId = crypto.randomBytes(32).toString('hex'); 
    requests[reqId] = { 
     context: this 
    } 

    yield next; 

    delete requests[reqId]; 
    } 
); 

    // route to kill request using ID generated from middleware above 
    router.get('/kill/:reqId', function *(next) { 
    var req = requests[this.params.reqId]; 

    if (req) { 
     // abort request here 
    } else { 
     this.body = { 
     error: 'Request not found' 
     }; 
    } 
    }); 
+0

Вы должны ввести токен отмены, который вы регулярно проверяете. – Jeff

ответ

2

Вы должны ввести токен отмены, который вы регулярно проверяете.

Пример:

// Factory to create a token 
const cancellationToken =() => { 
    let _cancelled = false; 

    function check() { 
    if (_cancelled == true) { 
     throw new Error('Request cancelled'); 
    } 
    } 

    function cancel() { 
    _cancelled = true; 
    } 

    return { 
    check: check, 
    cancel: cancel 
    }; 
} 


const reqs = {}; 

// Middleware to create tokens. 
app.use(function *(next) { 
    const reqId = crypto.randomBytes(32).toString('hex'); 
    const ct = cancellationToken(); 
    reqs[reqId] = ct; 
    this.cancellationToken = ct; 
    yield next; 

    delete reqs[reqId]; 
}); 

// route to kill request using ID generated from middleware above 
router.get('/kill/:reqId', function *(next) { 
    const ct = requests[this.params.reqId]; 

    if (ct) { 
    ct.cancel(); 
    } else { 
    this.body = { 
     error: 'Request not found' 
    }; 
    } 
}); 

// A request checking for cancellation. 
router.get('/longrunningtask', function *(next) { 
    for (let i = 0; i < 1000; i++) { 
    yield someLongRunningTask(i); 
    // This is where you check to see if you're done. 
    // The method will throw and abort the request. 
    this.cancellationToken.check(); 
    } 
}); 

Можно даже передать маркер отмены функции someLongRunningTask, так что вы можете контролировать аннулирование там.

+0

О, круто, я попробую, спасибо! –

+0

Я попытался сделать «setInterval» в промежуточном программном обеспечении, чтобы выполнить check(), но весь процесс узла был убит. Любая идея, если можно работать в setInterval? –

+0

Thats, потому что ошибка брошена и не поймана. – Jeff