原生的HTML5 API fetch并不支持timeout属性,习惯了jQuery的ajax配置的同学,如果一时在fetch找不到配置timeout的地方,也许会很纠结。fetch 的配置 API 如下:

语法

fetch(input, init).then(function(response) { ... });

参数

  • input

定义要获取的资源。这可能是:

一个 USVString 字符串,包含要获取资源的 URL。

一个 Request 对象。

  • init 可选

    一个配置项对象,包括所有对请求的设置。可选的参数有:

method: 请求使用的方法,如 GET、POST。

headers: 请求的头信息,形式为 Headers 对象或 ByteString。

body: 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。

mode: 请求的模式,如 cors、 no-cors 或者 same-origin。

credentials: 请求的 credentials,如 omit、same-origin 或者 include。

cache: 请求的 cache 模式: default, no-store, reload, no-cache, force-cache, or only-if-cached.

根本找不到timeout配置,本文和大家分享如何快速实现 fetch 的 timeout功能。

我们先实现abort功能,但由于初始化fetch后,返回的是一个Promise对象,那么需要在abort后达到触发rejectPromise的效果。

如果要沿用fetch返回的Promise来实现abort估计是达不到效果的,这里需要借助自己的一个Promise实例来达到目的。

var abort_fn = null;
var abort_promise = new Promise(function(resolve, reject) {
abort_fn = function() {
reject('abort promise');
};
});

这个简单的代码段,可以通过调用abort_fn 函数就可以触发abort_promise的reject

fetch 返回的promise 我们暂且称为 fetch_promise 吧,那么现在有两个 promise:abort_promisefetch_promise

每个promise都可以绑定resolve callback 和 reject callbck,那么后续then的回调绑定到哪个promise上呢,这是一个问题。

这里我们使用Promise非常好用的Promise.race方法, 他可以帮我们解决这个问题:

Promise.race 概述

Promise.race(iterable)方法返回一个promise,这个promise在iterable中的任意一个promise被解决或拒绝后,立刻以相同的解决值被解决或以相同的拒绝原因被拒绝。

合体:

function abortablePromise(fetch_promise) {
var abort_fn = null; //这是一个可以被reject的promise
var abort_promise = new Promise(function(resolve, reject) {
abort_fn = function() {
reject('abort promise');
};
}); //这里使用Promise.race,以最快 resolve 或 reject 的结果来传入后续绑定的回调
var abortable_promise = Promise.race([
fetch_promise,
abort_promise
]); abortable_promise.abort = abort_fn; return abortable_promise;
}

经过abortablePromise包裹后的promise都会返回一个新的promise,不同的是带上了一个abort方法。

使用例子:

var p = abortablePromise(fetch('//a.com/b/c'));
p.then(function(res) {
console.log(res)
}, function(err) {
console.log(err);
}); //假设fetch要3秒,但是你想在2秒就放弃了:
setTimeout(function() {
p.abort(); // -> will print "abort promise"
}, 2000);

目前为止,大体功能已经实现,再稍微调整,让调用更方便:

function _fetch(fetch_promise, timeout) {
var abort_fn = null; //这是一个可以被reject的promise
var abort_promise = new Promise(function(resolve, reject) {
abort_fn = function() {
reject('abort promise');
};
}); //这里使用Promise.race,以最快 resolve 或 reject 的结果来传入后续绑定的回调
var abortable_promise = Promise.race([
fetch_promise,
abort_promise
]); setTimeout(function() {
abort_fn();
}, timeout); return abortable_promise;
} //usage:
_fetch(fetch('//a.com/b/c'), 2000)
.then(function(res) {
console.log(res)
}, function(err) {
console.log(err);
});

此方法不仅用于fetch,也可以用于

全文完

让fetch也可以timeout的更多相关文章

  1. 封装fetch的使用(包含超时处理)

    // 1: 传统fetch操作 fetch('http://facebook.github.io/react-native/movies.json') .then((response) => r ...

  2. React Native 网络请求封装:使用Promise封装fetch请求

    最近公司使用React作为前端框架,使用了异步请求访问,这里做下总结: React Native中虽然也内置了XMLHttpRequest 网络请求API(也就是俗称的ajax),但XMLHttpRe ...

  3. 【译】XMLHttpRequest和Fetch, 谁最适合AJAX?

    原文地址:https://www.sitepoint.com/xmlhttprequest-vs-the-fetch-api-whats-best-for-ajax-in-2019/ 目录 从AJAX ...

  4. Kafka:主要参数详解(转)

    原文地址:http://kafka.apache.org/documentation.html ############################# System ############### ...

  5. kafka0.9.0及0.10.0配置属性

    问题导读1.borker包含哪些属性?2.Producer包含哪些属性?3.Consumer如何配置?borker(0.9.0及0.10.0)配置Kafka日志本身是由多个日志段组成(log segm ...

  6. Kafka主要参数详解(转)

    原文档地址:http://kafka.apache.org/documentation.html ############################# System ############## ...

  7. 转载:kafka参数详解

    原文:http://kafka.apache.org/documentation.html ############################# System ################# ...

  8. Kafka 设计与原理详解

    一.Kafka简介 本文综合了我之前写的kafka相关文章,可作为一个全面了解学习kafka的培训学习资料. 转载请注明出处 : 本文链接 1.1 背景历史 当今社会各种应用系统诸如商业.社交.搜索. ...

  9. MDN > Web technology for developers > HTTP

    The Hypertext Transfer Protocol (HTTP) is an application-layer protocol for transmitting hypermedia ...

随机推荐

  1. Android Studio使用百度地图示例BaiduMapsApiASDemo

    Android Studio使用百度地图示例BaiduMapsApiASDemo 用自己AVD下的debug.keystore替换掉项目中的debug.keystore 生成自己的签名 同样的方法生成 ...

  2. SHOPNC占用CPU过高

    今天一个SHOPNC商城突然变慢,查看服务器情况,发现MYSQL占用181%CPU,然后查看PHP慢查询,发现这样的内容 [22-Nov-2016 20:55:41] [pool www] pid 5 ...

  3. jquery的hide()和show()

    jquery用hide()和show()函数来控制html元素的显示和隐藏. hide()和show()都可以带参数的,hide(1000)表示隐藏所需的时间为1秒.此外还可以用slow,fast参数 ...

  4. delphi安装 Tclientsocket, Tserversocket控件

    菜单component->Install Packets按Add按钮,选择delphi目录里的bin目录下的dclsockets70.bpl(delphi2010是 dclsockets140. ...

  5. 从红米手机经常发生UIM没有服务的一些猜想

    缘起:买了测试用的红米手机,安装电信卡,经常生UIM没有服务,大约两天1次. 我的解决办法:飞行模式切换一下就恢复正常. 之前这张卡用三星的信号是满格,红米断开挺经常的 上网搜索: 同样的现象,还好官 ...

  6. 破解excel密码保护

    破解excel密码保护 录制一个新宏.内容如下.保存后运行,点几次确定,过一分钟还会再弹出来,再点确定,然后就好了. Public Sub AllInternalPasswords() ' Break ...

  7. 总结A*,Dijkstra,广度优先搜索,深度优先搜索的复杂度比较

    广度优先搜索(BFS) 1.将头结点放入队列Q中 2.while Q!=空 u出队 遍历u的邻接表中的每个节点v 将v插入队列中 当使用无向图的邻接表时,复杂度为O(V^2) 当使用有向图的邻接表时, ...

  8. A*搜索

    1,从点A开始,并且把它作为待处理点存入一个"开启列表".开启列表就像一张购物清单.尽管现在列表里只有一个元素,但以后就会多起来.你的路径可能会通过它包含的方格,也可能不会.基本上 ...

  9. Mac 终端命令大全

    目录操作 命令名 功能描述 使用举例 mkdir 创建一个目录 mkdir dirname rmdir 删除一个目录 rmdir dirname mvdir 移动或重命名一个目录 mvdir dir1 ...

  10. Python3实现最小堆建堆算法

    今天看Python CookBook中关于“求list中最大(最小)的N个元素”的内容,介绍了直接使用python的heapq模块的nlargest和nsmallest函数的解决方式,记得学习数据结构 ...