从 Promise 数组中删除 Promise 是否可行?

6
我希望能够创建一个既能处理同步行为又能处理异步行为的类似于这样的东西。 例如,我希望能够做到下面这样:
function timeout(myJson) {
    return new Promise(function (resolve, reject) {
        setTimeout(resolve, myJson.wait, myJson);
    });
}

async function funct() {
    try {
        let PromiseTolaunch = [{ "wait": 10, "nextIndex": 2, "id": 1 }, 
                                { "wait": 500, "nextIndex": -1, "id": 2 }, 
                                { "wait": 5, "nextIndex": -1, "id": 3 }];
        let launchedPromise = [], finishedPromise;

        launchedPromise.push(timeout(PromiseTolaunch[0]));
        launchedPromise[0].id = PromiseTolaunch[0].id;
        launchedPromise.push(timeout(PromiseTolaunch[1]));
        launchedPromise[1].id = PromiseTolaunch[1].id;
        while (launchedPromise.length !== 0) {
            finishedPromise = await Promise.race(launchedPromise);
        [*] console.log(finishedPromise); // Expected output: { "wait": 10, "nextIndex": 2 } 
            //console.log(launchedPromise); // Expected output : [Promise { { wait: 10, nextIndex: 2, id: 1 }, id: 1 }, Promise { <pending>, id: 2 } ]

            //I want to :
            //Remove the promise that just been executed from launchedPromise

            //console.log(launchedPromise); // Expected output : [ Promise { <pending>, id: 2 } ]
            if (finishedPromise.nextIndex !== -1) {
                launchedPromise.push(timeout(PromiseTolaunch[finishedPromise.nextIndex]));
            }
        }
        return Promise.resolve("done")
    } catch (error) {
        return Promise.reject(error);
    }
}

我希望在不影响 launchedPromise 的情况下,移除返回 finishedTest 的 Promise。

我已经尝试过:

launchedPromise.splice( lunchedTests.indexOf(finishedTest), 1 );
launchedPromise = lunchedTests.filter(prom => prom !== finishedTest);

显然它不起作用,因为(finishedTest !== PromiseToLunch[0]),它们甚至不是相同的类型,但我需要测试 ^^。我还尝试过访问PromiseValue,但没有成功。

如果我们只保留由[*]标记的console.log(),我想得到以下输出:

{ "wait": 10, "nextIndex": 2, "id": 1 }  
{ "wait": 5, "nextIndex": -1, "id": 3 }]
{ "wait": 500, "nextIndex": -1, "id": 2 }

2
小细节: 当你写lunch时,是否应该是launch? - Patrick Roberts
4
我实在无法确定你实际要解决的问题或你使用这段代码想达到什么结果。你能否解释一下你真正想要实现的目标,以避免 XY 问题 - Mike 'Pomax' Kamermans
2
如果你愿意给PromiseToLaunch中的每个对象添加一个id属性,那么你可以使用launchedPromise.findIndex()来查找.id === finishedPromise.id的索引,然后将该索引剔除。 - dx_over_dt
2
永远不要将async function作为执行器传递给new Promise - Bergi
2
不幸的是,Promise.race 不允许我们找出哪个 promise 先被解决。你必须自己记录这个过程。请参见例如 https://dev59.com/0pnga4cB1Zd3GeqPaZGn#38778887、https://dev59.com/xFUL5IYBdhLWcg3wSWRu#50586391 或 https://dev59.com/aFkT5IYBdhLWcg3wAK9E#39197252 等方法。 - Bergi
显示剩余4条评论
1个回答

3

所以,回答这篇文章的问题的函数是:

for (let i = 0; i < LaunchedTests.length; i++) {
    if (LaunchedTests[i].id === finishedTest.scenario + finishedTest.name) {
        return Promise.resolve(LaunchedTests.splice(i, 1));
    }
}
return Promise.reject("not find");

但是首先您需要初始化一个ID,如下所示:
let PromiseTolaunch = [{ "wait": 10, "nextIndex": 2, "id": 1 }, 
                       { "wait": 500, "nextIndex": -1, "id": 2 }, 
                       { "wait": 5, "nextIndex": -1, "id": 3 }];
let launchedPromise = [], finishedPromise;
launchedPromise.push(timeout(PromiseTolaunch[0]));
launchedPromise[0].id = PromiseTolaunch[0].id;
launchedPromise.push(timeout(PromiseTolaunch[1]));
launchedPromise[1].id = PromiseTolaunch[1].id;

您的承诺将采用以下形式:Promise { <pending>, id: YourId },您可以通过传递findIndex()函数来访问它,然后只需要使用splice即可。感谢@dx-over-dt和所有帮助我的人!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接