Javascript 是否可以为每个承诺使用带有 then() 的 axios.all ?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43664566/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to use axios.all with a then() for each promise?
提问by nanoguy
I have a React component that triggers an event to fetch data. This results in a dynamic number of stored proc calls to fetch data, and the data from each call is stored in a totally different location. Then I need to re-render once all of the data is received and available. I'm using promises with axios.
我有一个 React 组件,它触发一个事件来获取数据。这会导致动态数量的存储过程调用来获取数据,并且每次调用的数据都存储在完全不同的位置。然后我需要在收到所有数据并可用后重新渲染。我在 axios 中使用 promise。
Since the number of axios calls is dynamic, I'm building an array and inserting it into axios.allas follows:
由于 axios 调用的次数是动态的,我正在构建一个数组并将其插入axios.all如下:
let promises = [];
for (let i = 0; i < requests.length; i++) {
promises.push(axios.get(request[i].url, { params: {...} }));
}
axios.all(promises).then(/* use the data */);
The problem is that each axios request returns data that gets added to an object in a totally different place. Since I have no way to put them all in the correct place in a single then(how would I know which response goes in which location?), I tried doing something like this:
问题是每个 axios 请求返回的数据都被添加到一个完全不同的地方的对象中。由于我无法将它们全部放在一个正确的位置then(我怎么知道哪个响应位于哪个位置?),我尝试做这样的事情:
let promises = [];
for (let i = 0; i < requests.length; i++) {
promises.push(
axios.get(request[i].url, { params: {...} })
.then(response => {myObject[request[i].saveLocation] = response.data;})
);
}
axios.all(promises).then(/* use the data */);
However, this doesn't work as I expected. The thenafter each getis executed, but not until well after the thenattached to axios.all. Obviously this is a problem because my code tries to use the data before it has been saved to the object.
但是,这并不像我预期的那样工作。在then每次使用后get执行,但直到好后then附着axios.all。显然这是一个问题,因为我的代码试图在将数据保存到对象之前使用它。
Is there a way to have a separate thencall for each axios.getthat will be executed after its corresponding promise is resolved, and then have a final thenthat will be executed only after allof the promises are resolved, to use the data now that the object has been populated?
有没有办法then对每个axios.get将在其相应的承诺解决后执行的单独调用,然后有一个then仅在所有承诺解决后才执行的最终调用,以使用对象已经被解决的数据人口稠密?
回答by nanoguy
Okay, so I found a way to do what I needed without using using a thenon each get. Since the params passed in to axios.getcontain enough info to determine the save location, and since I can read the params back from the response, I can do something like the following:
好的,所以我找到了一种无需then在每个get. 由于传入的参数axios.get包含足够的信息来确定保存位置,并且由于我可以从响应中读取参数,因此我可以执行以下操作:
let promises = [];
for (let i = 0; i < requests.length; i++) {
promises.push(axios.get(request[i].url, { params: {...} }));
}
axios.all(promises)
.then(axios.spread((...args) => {
for (let i = 0; i < args.length; i++) {
myObject[args[i].config.params.saveLocation] = args[i].data;
}
}))
.then(/* use the data */);
This ensures all the data is received and saved to the object before it is used.
这可确保在使用之前接收所有数据并将其保存到对象中。
回答by trincot
If the behaviour of your second attempt is indeed like that, then that would be an indication that axiosis not Promise/A+ compliant. The thencallback's return value must be the value with which the promise returned by that thenis fulfilled. Since that is the promise you push into the array, the value that axios.allwould return for that promise can only be known by executing the thencallbacks first.
如果您第二次尝试的行为确实如此,那么这将表明axios不符合 Promise/A+。该then回调的返回值必须与它通过返回的承诺的价值then满足。由于这是您推送到数组axios.all中的承诺,因此只能通过then首先执行回调来了解该承诺的返回值。
Event though you do not return a value explicitly in the thencallback, this does not affect the above rule: in that case the return value is undefinedand it is thatvalue that should be provided by axios.allonce the corresponding promise is resolved.
事件虽然你不会在明确返回值then的回调,这并不影响上述规则:在这种情况下返回值是undefined,它是那应该由提供价值axios.all,一旦相应的承诺得到解决。
See in particular the rules 2.2.7, 2.2.7.1, 2.3.2.1, 2.3.2.2 in the specs of Promise/A+).
特别参见Promise/A+ 规范中的规则 2.2.7、2.2.7.1、2.3.2.1、2.3.2.2 )。
So I would suggest using a Promise/A+ compliant promise implementation instead. There are several other libraries, like for instance request-promise.
所以我建议改用符合 Promise/A+ 的承诺实现。还有其他几个库,例如request-promise。
Alternatively, you could use the native ES6 Promise implementation, and promisify the http.requestmethodyourself.
或者,您可以使用原生 ES6 Promise 实现,并自己承诺该http.request方法。
ES6 offers Promise.allwhich guarantees to provide the resolved values in the same order as the promises were provided.
ES6 提供Promise.all哪些保证以与提供承诺相同的顺序提供已解析的值。
回答by mohamed hussein
your initial code could work normally as intended if you pass the promises to your array attached with their respective thenfunction
如果您将承诺传递给附带各自then函数的数组,您的初始代码可以按预期正常工作
let promises = []; // array to hold all requests promises with their then
for (let i = 0; i < requests.length; i++) {
// adding every request to the array
promises.push(
axios.get(request[i].url, { params: { ...} })
.then(response => { myObject[request[i].saveLocation] = response.data; })
);
}
// Resolving requests with their callbacks before procedding to the last then callback
axios.all(promises).then(/* use the data */);

