javascript - 能够中止异步调用

标签 javascript node.js asynchronous babeljs ecmascript-2016

我正在使用 babeljs 和 es7 风格的 async/await 方法。我有一个主脚本,它将在所有返回 promise 的对象数组上调用异步方法。我使用 Promise.all() 等待所有这些任务返回,但是,这些任务可能需要很长时间,如果它们超过阈值,我想中止所有这些任务,并且任务以适当的方式处理。

到底有没有办法完成这样的事情?目前我能想到的唯一方法是生成一个进程来执行调用这些方法的工作并等待它们全部解决,如果达到时间限制,它可以终止进程并执行它需要的任何处理。

更新:关于主脚本正在等待的这些方法的一些说明......他们可能正在执行一系列操作(调用外部系统、在某处流式传输文件等)并且没有执行一个可能被取消的操作独立。

更新 #2:一些未经测试的半伪代码

class Foo1 {
    async doSomething() {
        // call some external system
        // copy some files
        // put those files somewhere else (s3)
    }
}
class Foo2 {
    async doSomething() {
        // Do some long computations
        // Update some systems
    }
}

class FooHandler {
    constructor() {
        this.fooList = [];
    }

    async start() {
        await Promise.all(this.fooList.map(async (foo) => {
            return await foo.doSomething();
        }));
    }
}

let handler = new FooHandler();

handler.fooList.push(new Foo1());
handler.fooList.push(new Foo2());

// if this call takes too long because of slow connections, errors,   whatever,
// abort start(), handle it in whatever meaningful way, and continue on.
await handler.start();

最佳答案

原生 ES6 promise 目前不支持直接取消。很多地方一直在谈论它,但还没有。

由于原生 Promise 不支持它并且 async/await 适用于 Promise,因此目前没有内置的简单方法可以中止它。一种常见的方法是在创建返回 promise 的操作时使用 token 。

假设您已 promise XHR GET:

// simplification
function ajax(url){
    return new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest;
        xhr.open("GET", url);
        xhr.onload = () => resolve(xhr.responseText);
        xhr.onerror = reject;
        xhr.send();
    });
}

现在你想使用它:

async function foo(){
    let result = await ajax("/myApi");
    let result2 = await ajax("/myApi2?token=" + result);
}

现在,假设我们想在某些情况下取消 AJAX,我们可以这样传递一个 token :

function ajax(url, token = {}){
    return new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest;
        xhr.open("GET", url);
        Object(token).cancel = () => { xhr.abort(), reject(); };
        xhr.onload = () => resolve(xhr.responseText);
        xhr.onerror = reject;
        xhr.send();
    });
}

这会让你这样做:

async function foo(){
    let token = {};
    let req = ajax("/myApi", token); // note no await
    // now let's say we want to abort the request since we don't 
    // need the data
    token.cancel(); // this will abort the token
}

这种方法需要与链接一起工作,幸运的是,对于 ES6 语法,这没什么大不了的。祝你好运,编码愉快。

关于javascript - 能够中止异步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29592680/

相关文章:

javascript - 可变数量的切片 : Pie Chart concept

node.js - Node js strip 连接缺少requested_capability : ['card_payments' ] param from create account function

node.js - 使用 npm 我如何将包下载为 zip,包中包含其所有依赖项

node.js - 为什么 Windows 无法识别 Node 版本管理器 (NVM)?

api - 为什么要使用异步/非阻塞框架构建 API?

Javascript:如何根据 html 标签扩展用户选择?

javascript - jQuery post - 等待响应

javascript - Django 中的 jQuery : Uncaught TypeError: Cannot read property 'createDocumentFragment' of null

android - android中如何进行同步?

ios - completionHandler 不能在 Xcode 的单元测试中执行,例如。异步 api - CLGeocoder 的 reverseGeocodeLocation