更新:添加了一个更简单的jsfiddle演示,
https://jsfiddle.net/47sfj3Lv/3/
.
用更少的代码重现这个问题,我正试图从jQuery中摆脱出来。
我的一些用于填充某些表的代码有这样的代码
var hb = new hbLister(url: '#attributes.listURL#')
.getData(#url.page#, #url.per#)
.search(searchColumn, searchParam)
.render();
-
hbLister
会初始化一些东西
-
getData
将执行$.ajax调用
-
search
将
console.log('filtering data')
并对javascript对象应用搜索条件
-
render
重要的是,
在ajax调用之前不会启动
获取数据
现在我有了这个ajax构造函数。我已经尽可能地简化了这段代码。
let ajax = function (options, hooks, headers) {
let that = this;
// enforce parameter types
// copy parameters to this.base
this.base = { options: options, hooks: hooks, headers: headers }
return function (url, options, data, hooks, headers) {
// enforce variable types
// merge options and hooks with their base.counterparts
headers = new Headers(Object.assign({}, that.base.headers, headers));
options.headers = headers;
return fetch(url, options)
.then(response => {
return response.json().then(json => {
console.log('processing');
if (response.ok) {
// it's omitted here but the Base functions are defined
// in the constructor parameters
hooks.successBase(json, response.status, response.headers);
hooks.success(response.json, response.status, response.headers)
} else {
hooks.failureBase(json, response.status, response.headers);
hooks.failure(response.json, response.status, response.headers)
}
})
});
}
}
我可以说
let tableLister = new ajax()
然后
可以打电话
tableLister = tableLister(hb.url, // url
{ type: "GET" }, // options
config.data, // data
{ success: successFn } // hooks, success being the callback
)
jQuery调用会正确地给我
processing
filtering data
.
这个函数给了我
处理
因为我好像拿不到锁链(
.search(...).render()
)等待ajax调用完成。
下面是一个关于jsFiddle的独立示例,
https://jsfiddle.net/47sfj3Lv/3/
我确信答案是异步的,等待着,但我还没能让它工作。
这是我尝试过的一个例子
return await (async function () {
console.log('fetching')
let fetcher = await fetch(url, options);
console.log('getting json');
return await fetcher.json().then((json) => {
console.log('have json, doing hooks');
if (fetcher.ok) {
let argXHR = { json: json}
hooks.successBase(argXHR, hooks.params);
hooks.success.forEach(v => v(argXHR, hooks.params));
hooks.afterSend(argXHR, hooks.params);
} else {
let argXHR = { json: json,}
hooks.failureBase(argXHR, hooks.params);
hooks.failure.forEach(v => v(argXHR, hooks.params));
hooks.afterError(argXHR, hooks.params);
}
console.log('finished hooks')
})
}())
不管我怎么做,在等待结束之前,锁链还在继续。。
.getData().search(...).render()
)可以这样做,因为这不允许ajax函数在请求完成和回调执行之前返回**我还是更愿意
.fetch()
let xhr = new XMLHttpRequest()
let urlParams = [];
Object.keys(data).forEach((v) => urlParams.push(v + '=' + encodeURIComponent(data[v])));
urlParams = urlParams.join('&')
xhr.open(options.method, options.url, false);
xhr.onreadystatechange = function(state) {
if (this.readyState == 4) {
let json = JSON.parse(xhr.responseText)
hooks.successBase(json, xhr.status, xhr.getResponseHeader);
hooks.success.forEach(v => v(json, xhr.status, xhr.getResponseHeader));
}
}
xhr.onerror = function() {
let json = JSON.parse(xhr.responseText)
hooks.failureBase(json, xhr.status, xhr.getResponseHeader);
hooks.failure.forEach(v => v(json, xhr.status, xhr.getResponseHeader));
}
for (h in headers) {
xhr.setRequestHeader(h, headers[h])
}
xhr.send(urlParams)