使用 JavaScript Promise All - 这个语法有效吗?
Using JavaScript Promise All - is this syntax valid?
我有两个 table 用户,其中一个用户的每个 ID 在两个 table 中都是相同的(不要问为什么我有两个用户 table) .
在某些时候,我需要从 table 1 中过滤用户,如果某些条件为真,我将每个用户的承诺(删除请求)存储到(我们称之为)tableOnePromises 中。我对 table 2 做同样的事情。
为了清空 table 2,由于某些要求,我必须先清空 table 一个。
这就是我所做的:
let tableOnePromises = [];
let tableTwoPromises = [];
tableOne.forEach(item => {
if(item.deactivated) {
const tableOneDeleted = supabase
.from("table-one")
.delete()
.match({id: item.id});
tableOnePromises.push(tableOneDeleted);
const tableTwoDeleted = supabase
.from("table-two")
.delete()
.match({id: item.id});
tableOnePromises.push(tableTwoDeleted);
}
});
await Promise.all(tableOnePromises).then(() => {
return Promise.all(tableTwoPromises)
}).catch(err => console.log(err));
假设使用 await
的代码在 async
函数内(或在模块的顶层),语法 是正确的,但是它可能不是我要使用的(一般来说,避免将 async
/await
与通过 .then
和 .catch
的显式回调混合使用),并且单独它可能无法正常工作您期望的(这可以通过您说您的代码无法从 table-two
中删除来证实)。
对于任何特定的 id
值,您的代码开始从 table-one
中删除,然后 立即 开始从 table-two
中删除而不等待删除 table-one
完成:
// STARTS the deletion but doesn't wait for it to finish
const tableOneDeleted = supabase
.from("table-one")
.delete()
.match({id: item.id});
// ...
// Starts deleting from `table-two`, even though the item may still be in `table-one`
const tableTwoDeleted = supabase
.from("table-two")
.delete()
.match({id: item.id});
请记住,承诺只是观察异步过程的一种方式;当你得到承诺时,它所观察的过程已经在进行中。因此,即使你没有等到 table-two
承诺,你也会立即开始 table-two
删除。
...I MUST first empty table one due to some requirements...
如果说“空”,您的意思只是您必须确保在 table-one
上完成特定 id
的 delete
,然后再在 [=20= 上完成],需要等待table-one
删除完成后才能开始table-two
删除。我会把它放在一个函数中:
async function deleteItem(id) {
await supabase
.from("table-one")
.delete()
.match({id});
await supabase
.from("table-two")
.delete()
.match({id});
}
那么代码就变成了:
const promises = [];
for (const {deactivated, id} of tableOne) {
if (deactivated) {
promises.push(deleteItem(id));
}
}
await Promise.all(promises); // With the `try`/`catch` if desired
...或者如果可以两次遍历数组:
await Promise.all( // With the `try`/`catch` if desired
tableOne.filter(({deactivated}) => deactivated)
.map(({id}) => deleteItem(id))
);
¹ “...当您得到承诺时,它正在观察的过程已经在进行中。” 这是正常情况。不幸的是,有一个流行的文档 DB 库没有开始它的工作 until/unless 你称之为 then
的承诺。但这是一个例外,anti-pattern.
我有两个 table 用户,其中一个用户的每个 ID 在两个 table 中都是相同的(不要问为什么我有两个用户 table) . 在某些时候,我需要从 table 1 中过滤用户,如果某些条件为真,我将每个用户的承诺(删除请求)存储到(我们称之为)tableOnePromises 中。我对 table 2 做同样的事情。 为了清空 table 2,由于某些要求,我必须先清空 table 一个。 这就是我所做的:
let tableOnePromises = [];
let tableTwoPromises = [];
tableOne.forEach(item => {
if(item.deactivated) {
const tableOneDeleted = supabase
.from("table-one")
.delete()
.match({id: item.id});
tableOnePromises.push(tableOneDeleted);
const tableTwoDeleted = supabase
.from("table-two")
.delete()
.match({id: item.id});
tableOnePromises.push(tableTwoDeleted);
}
});
await Promise.all(tableOnePromises).then(() => {
return Promise.all(tableTwoPromises)
}).catch(err => console.log(err));
假设使用 await
的代码在 async
函数内(或在模块的顶层),语法 是正确的,但是它可能不是我要使用的(一般来说,避免将 async
/await
与通过 .then
和 .catch
的显式回调混合使用),并且单独它可能无法正常工作您期望的(这可以通过您说您的代码无法从 table-two
中删除来证实)。
对于任何特定的 id
值,您的代码开始从 table-one
中删除,然后 立即 开始从 table-two
中删除而不等待删除 table-one
完成:
// STARTS the deletion but doesn't wait for it to finish
const tableOneDeleted = supabase
.from("table-one")
.delete()
.match({id: item.id});
// ...
// Starts deleting from `table-two`, even though the item may still be in `table-one`
const tableTwoDeleted = supabase
.from("table-two")
.delete()
.match({id: item.id});
请记住,承诺只是观察异步过程的一种方式;当你得到承诺时,它所观察的过程已经在进行中。因此,即使你没有等到 table-two
承诺,你也会立即开始 table-two
删除。
...I MUST first empty table one due to some requirements...
如果说“空”,您的意思只是您必须确保在 table-one
上完成特定 id
的 delete
,然后再在 [=20= 上完成],需要等待table-one
删除完成后才能开始table-two
删除。我会把它放在一个函数中:
async function deleteItem(id) {
await supabase
.from("table-one")
.delete()
.match({id});
await supabase
.from("table-two")
.delete()
.match({id});
}
那么代码就变成了:
const promises = [];
for (const {deactivated, id} of tableOne) {
if (deactivated) {
promises.push(deleteItem(id));
}
}
await Promise.all(promises); // With the `try`/`catch` if desired
...或者如果可以两次遍历数组:
await Promise.all( // With the `try`/`catch` if desired
tableOne.filter(({deactivated}) => deactivated)
.map(({id}) => deleteItem(id))
);
¹ “...当您得到承诺时,它正在观察的过程已经在进行中。” 这是正常情况。不幸的是,有一个流行的文档 DB 库没有开始它的工作 until/unless 你称之为 then
的承诺。但这是一个例外,anti-pattern.