【问题标题】:Abort Xhr on cujojs rest.js在 cujojs rest.js 上中止 Xhr
【发布时间】:2015-12-30 07:17:40
【问题描述】:

我正在使用 cujojs/rest 向我的 (laravel) API 发送请求。我正在寻找一种方法来取消新请求时尚未结束的请求。

客户端上有一个取消方法,这可能是我解决问题所需要的:

我的应用显示了一个分页的项目集合,人们可以通过单击“下一个/上一个”按钮来浏览页面。 如果用户快速多次单击“下一步”按钮,则每个新页面都会触发一个新请求。我想确保只有最新的请求才能进行,而所有其他(未完成的)请求都被中止。

当我使用另一个工具来执行我的请求时,我曾经使用 beforeSend 方法来执行此操作。它会将 xhr 对象添加到数组中,并且在触发请求之前,如果它们没有结束,它将对该数组中的所有 xhr 调用 .abort()。

现在我切换到 cujojs/rest,我不知道如何使用取消方法来完成。

当然,我不想在运行新请求之前中止任何请求,只是那些利用相同资源的请求,因为我可能在其他地方加载了不相关的数据。

/users?page=1 -> should be canceled
/users?page=2 -> should be canceled
/preferences  -> should NOT be canceled
/users?page=3 -> should be canceled
/users?page=4 -> should go through as its the last one

任何帮助将不胜感激。

【问题讨论】:

  • 一旦请求被发送,你就不能取消它,因为取消将是另一个请求,它不会比前一个更快地传递到服务器端,所以你需要在你的代码中过滤它得到回应
  • 但这不是你在使用 beforeSend 时所做的:stackoverflow.com/questions/4551175/…
  • beforeSend 事件完全按照它的写入方式触发,这意味着在发送请求之前。一旦从技术上发送,您将永远无法遗憾地取消它。但这是合乎逻辑的。但据我了解,您需要在发送之前取消它,问题是如何使用 cujojs 进行操作
  • 如果您提供您的代码,我可能会提供帮助。似乎 cujojs 有 cancel 方法,所以基本上在发送请求之前你可以运行 .cancel() 它会取消所有尚未发送的请求
  • 对,我正在用 VueJs 构建一个应用程序。我正在观看一个“页面”属性,当它发生变化时,它会再次触发一个 fetch 方法。

标签: javascript ajax rest request xmlhttprequest


【解决方案1】:

我不确定,因为据我所知没有适当的文档。但是从源代码来看你应该可以做这样的事情

//lets say you defined **this.request** somewhere in the constructor to hold the request value which defaults to empty object {};

fetchCollection: function(id) {

var that = this;
var url = 'collections/' + id;

if( Object.keys( that.request ).length !== 0 ) {

    if( 'function' === typeof that.request.cancel )
         that.request.cancel();
    else
         that.request.canceled = true;

  //here we should re-assign the default {} value again
  that.request = {};


}
that.request.path = url;

return client( that.request ).then(
        function(response){
            that.collection = response.entity.data;
        },
        function(response){
            console.error(response.status.code, response.status);
        }
    );
},

如果有效,我可以解释原因。

好的,现在我可以解释为什么使用伪代码了:

client( request ) 函数中 cujojs 在做任何事情之前这样做:

  1. 检查 request.canceled 是否存在且等于 true

  2. 如果满足条件则中止请求

如果 request.canceled 不存在,则继续并进入下一步

  1. cujojs 定义了 request.cancel 函数,它可以在请求发送之前中止请求(我们不关心之后的步骤,因为取消是我们的意图)

现在我们正在做的是使用 javascript 的先天能力通过引用传递变量。 通过引用意味着当你给 create() 函数一个变量 request 时,该函数在自身内部使用这个相同的变量,而不是创建一个变量 request 的全新副本并使用该副本。

我们在这里利用它的方式是我们从 cujojs 外部操作 request 变量,知道它使用相同的变量,因此我们的操作将直接影响 request 变量 cujojs 在执行 create() 函数时使用。

现在我们知道 cujojs 有 2 种取消请求的方法,并且我们可以在 create() 函数收到它之后操作 request 变量,我们做一个简单的检查我们这边:

  1. 我们检查 this.request 是否为空(只有在尚未发送请求时才会为空)

  2. 如果不为空,我们检查 cujojs 是否已经在我们的 request 变量上定义了 .cancel 函数,方法是 'function' === typeof request.cancel

  3. 如果有我们可以使用这个函数来取消我们之前发送的请求, 如果我们不知道 cujojs 现在正在检查 .canceled 变量上的 request 变量的步骤,因此我们将其分配给真正做 this.request.canceled = true;

  4. 取消请求后,我们为 request 赋予了全新的值 {} 从而失去了对我们之前的 reference request 我们之前操作的变量

我很不擅长解释事情,但我希望你能理解,了解这些细微差别会对你的发展有很大帮助。

愉快的编码

【讨论】:

  • 如果您有时间,不介意解释一下。我需要找到一种方法来提取它,因为我经常这样做。非常感谢!
  • 也许这可以在拦截器中处理.. 他们有一个超时拦截器 (github.com/cujojs/rest/blob/master/interceptor/timeout.js)。功能有点相似。但它应该只取消相同的请求(例如页面查询除外)。不过,这太让我头疼了。
  • 我添加了解释。如果你认为你可以从这里继续它的酷炫,否则只需编写,我会尝试将它包装在一段可重用的代码中。这会很难,因为我对 cujojs 和 node.js 一无所知,所以在响应之前无法对其进行测试。我想说的是,如果您了解它的工作原理并应用它会更好根据您的 cujojs 知识。但是,如果只是在这里写点什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-17
  • 2014-08-14
相关资源
最近更新 更多