[英]filtering a promise iterated result array into a new array vue js
如何将旧数组的值插入到新的 arr promise 中。 由于 vue 的反应性,需要一种拼接方法。 不知何故 newArray 是空的,没有得到任何值。 https://codesandbox.io/s/sweet-sammet-fyomv0?file=/src/components/Example2.vue
<template> <div class="hello"> <h1>Example 2</h1> <input @click="send" type="button" value="Send" /> <div class="out" v-if="successIds.length">{{ successIds }}</div> </div> </template> <script> /* @return resolve: { id: 1, success: true } or reject: { success: false } */ const fakeApiRequest = (id) => { return new Promise((resolve, reject) => { setTimeout(() => { const success = id % 2; success? resolve({ id, success }): reject({ success }); }, 2000); }); }; export default { data() { return { // Fetch ids ids: [1, 2, 3, 4, 5, 6], // Complete ids successIds: [], }; }, methods: { async send() { let newArr = await Promise.allSettled( this.ids.map(fakeApiRequest).filter((promise) => promise.status === "fulfilled").map((promise) => promise.value) ); // console.log(newArr) --> gets an empty array this.successIds.splice(0, 0, newArr); }, }, }; </script> <style scoped>.out { margin: 20px 0; color: #41b883; } </style>
您只能对Promise.allSettled()
的等待结果应用过滤器。 所以你要么这样做( await
然后在等待的结果上应用过滤器)或者将过滤器放在它的then
上:
工作示例:
const { createApp, defineComponent } = Vue; const fakeApiRequest = (id) => { return new Promise((resolve, reject) => { setTimeout(() => { const success = id % 2; success? resolve({ id, success }): reject({ success }); }, 2000); }); }; const Test = defineComponent({ template: "#test", data() { return { ids: [1, 2, 3, 4, 5, 6], successIds: [], }; }, methods: { async send() { this.successIds = [] this.successIds = await Promise.allSettled( this.ids.map(fakeApiRequest) ).then((results) => results.filter(({ status }) => status === "fulfilled").map(({ value }) => value.id) ); }, }, }); createApp({ components: { Test }, }).mount("#app");
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script> <div id="app"> <test /> </div> <template id="test"> <div class="hello"> <h1>Example 2</h1> <input @click="send" type="button" value="Send" /> <div class="out" v-if="successIds.length">{{ successIds }}</div> </div> </template>
旁注:您不需要splice
结果以保持反应性。 如果您失去反应性,您应该提出一个单独的问题,提供足够的细节。 如您所见,它在我的示例中运行得非常好。
几个问题:
您正在对.filter
调用返回的承诺应用.map
调用,但承诺没有可作为过滤依据的status
属性。 您只能过滤已解决的值,而不能过滤承诺。 所以首先需要等待allSettled
promise的解析,才能开始过滤。
splice
期望插入值是单独的 arguments,而不是数组。 所以使用传播语法
当您想用id
值填充successIds
,并且 api 返回具有id
和success
属性的对象时,您仍然需要从每个 object 中提取该id
属性。
这是一个更正(我删除了 vue 依赖项):
const fakeApiRequest = (id) => { return new Promise((resolve, reject) => { setTimeout(() => { const success = id % 2; success? resolve({ id, success}): reject({ success }); }, 200); }); }; const app = { data() { return { // Fetch ids ids: [1, 2, 3, 4, 5, 6], // Complete ids successIds: [], }; }, methods: { async send() { const results = await Promise.allSettled( this.ids.map(fakeApiRequest) ); const ids = results.filter((settled) => settled.status === "fulfilled").map((settled) => settled.value.id); this.successIds.splice(0, 0, ...ids); console.log(this.successIds); // for this demo only }, }, }; // Mimic vue app.methods.send.call(app.data());
您需要在解决后过滤承诺:
const promises = this.ids.map(fakeApiRequest)
const settledPromises = await Promise.allSettled(promises);
const values = settledPromises.filter(p => p.status === "fulfilled").map(p => p.value)
this.successIds = values.concat(this.successIds)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.