我需要一种接受promise的方法,在它上面调用.then来检查返回值,然后将这个promise完全按照它返回给系统的其他部分。上下文是这样的:我正在尝试修改GraseMonkey脚本中的fetch API,以便能够修改返回的数据。我通过在响应上调用.json()来检查这一点。但是,如果我不修改数据,我需要返回一个对象,该对象准确地表示对fetch API的原始调用,这样页面的代码就看不到任何差异。但是,当我尝试返回对象时,我得到一个错误,即响应已经被使用,现在我迷失在一堆我似乎无法解决的承诺中(我不是JS原生用户)
下面的代码是我已经有的代码,它可以工作,但它不是真正可以接受的,因为它复制了所有其他没有被破坏的请求。
function newFetch(){
if (needsToBeModified(arguments[0])) {
response = null;
return oldFetch.apply(this, arguments)
.then(r => {
response = r;
return r.json();
})
.then(
j => {
j = processJSON(j);
return new Promise((resolve, rej) => {
response.json = () => new Promise((resolve, reject) => resolve(j));
resolve(response);
});
},
(fail) => {
return oldFetch.apply(this, arguments)
//How can I avoid making this call here again?
}
);
} else {
return oldFetch.apply(this, arguments);
}
}
请告诉我一种偷看json的方法,如果这抛出了一个错误,那么从fetch返回原始的承诺,而不需要再次调用?
谢谢。
发布于 2018-06-08 01:47:13
就像@jfriend建议的那样,您将需要clone
响应,以便您的调用者可以在检查JSON之后再次使用它:
function newFetch(urlOrRequest) {
var promise = oldFetch.apply(this, arguments);
if (needsToBeModified(urlOrRequest)) {
return promise.then(response =>
response.clone().json().then(obj => {
const result = Promise.resolve(processJSON(obj));
response.json = () => result;
return response;
}, jsonErr => {
return response;
})
);
} else {
return promise;
}
}
或者更好的方法是,只返回create a new one,而不是返回带有修补的json
方法的未更改的旧响应
function newFetch(urlOrRequest) {
var promise = oldFetch.apply(this, arguments);
if (needsToBeModified(urlOrRequest)) {
return promise.then(response =>
response.clone().json().then(obj => {
const result = JSON.stringify(processJSON(obj));
return new Response(result, response);
}, jsonErr => response)
);
} else {
return promise;
}
}
或者,最简单的方法是将processJSON
调用推迟到被覆盖的json
方法中:
…
if (needsToBeModified(urlOrRequest)) {
return promise.then(response =>
response.json = function() {
return Response.prototype.json.call(this).then(processJSON);
};
return response;
});
}
…
发布于 2018-06-07 04:24:31
我想我理解这个问题,有时候你需要根据它的参数改变异步操作的结果
不需要执行两次操作,我认为操作码可以大大简化如下:
function newFetch() {
return oldFetch.apply(this, arguments).then(r => {
return (needsToBeModified(arguments[0]))? processJSON(r.json()) : r;
});
}
https://stackoverflow.com/questions/50728411
复制相似问题