【问题标题】:Javascript filter method returning the original array even when returned falseJavascript 过滤器方法返回原始数组,即使返回 false
【发布时间】:2021-06-02 20:53:42
【问题描述】:

我有一个过滤方法如下:

    let newArray = Alerts[symbol].filter(async (alert: IDiscordSymbolAlert, alert_index: number) => {
        // If Price when set is greater than alert price, price has to move UP to trigger
        if (alert.price_when_set < alert.alert_price) {
            hasToGo = Change.UP;
        } 
        // If Price when set is greater than alert price, price has to move DOWN to trigger
        else if (alert.price_when_set > alert.alert_price){
            hasToGo = Change.DOWN;
        }

        /**If the hasToGo is UP and current price is greater than alert price, then ALERT USER [OR]
        // If the hasToGo is DOWN and current price is lesser than alert price, then ALERT USER **/ 
        if((hasToGo === Change.UP && (price >= alert.alert_price)) ||
        (hasToGo === Change.DOWN && (price <= alert.alert_price))) {
            /**
             * Send Notification that alert has been hit
             */
            let userToSend = await discord.users.fetch(alert.userID)
            if(!userToSend) return;
            //@ts-ignore
            userToSend.send(`> @everyone\n\n${symbol} has reached your alert price - ${alert.alert_price}`);
            // remove that alert
            guild_modified = true;
            return false;
        }

        return true;
    });


    // When logged here, it shows the entire array even though certain values have returned false.
    // I know they returned false because the block in which they returned false was executed and 
     //i did receive a notification which was executed in the same block.

    console.log(newArray);

在此处登录(console.log) 时,即使某些值返回 false,它也会显示整个数组。我知道他们返回 false 是因为他们返回 false 的块已执行,并且我确实收到了在同一块中执行的通知。我知道这与async/await 有关,但我不确定是什么。有人可以看看吗。

更新问题

Alerts[symbol].forEach(async (alert: IDiscordSymbolAlert, alert_index: number) => {
        // If Price when set is greater than alert price, price has to move UP to trigger
        if (alert.price_when_set < alert.alert_price) {
            hasToGo = Change.UP;
        } 
        // If Price when set is greater than alert price, price has to move DOWN to trigger
        else if (alert.price_when_set > alert.alert_price){
            hasToGo = Change.DOWN;
        }

        /**If the hasToGo is UP and current price is greater than alert price, then ALERT USER [OR]
        // If the hasToGo is DOWN and current price is lesser than alert price, then ALERT USER **/ 
        if((hasToGo === Change.UP && (price >= alert.alert_price)) ||
        (hasToGo === Change.DOWN && (price <= alert.alert_price))) {
            /**
             * Send Notification that alert has been hit
             */
            let userToSend = await discord.users.fetch(alert.userID)
            if(!userToSend) return;
            //@ts-ignore
            userToSend.send(`> @everyone\n\n${symbol} has reached your alert price - ${alert.alert_price}`);
            // remove that alert
            Alerts![symbol].splice(alert_index, 1);
            guild_modified = true;
        }
    });

    console.log(Alerts[symbol]);

因为在这种情况下过滤器不能与async/await 一起使用。这是我使用forEach() 循环并使用splice() 手动删除数组中的匹配对象。但是由于 forEach 本身是异步的,并且 console.log 在异步块之外起​​作用。它不是返回新数组,而是返回未修改的数组。如何返回要在 forEach 块范围之外使用的新数组。

提前致谢!

【问题讨论】:

    标签: javascript typescript async-await es6-promise array-filter


    【解决方案1】:

    您不能将async 函数与filter 一起使用。 filter 返回回调为其返回真值的所有元素。 async 函数总是返回 promise,它们是对象,所有非 null 对象都是真实的。

    如果你的filter检查需要async,那么你的整个操作就是async并且需要这样处理。

    这是一个现成的async 过滤函数,它并行执行元素检查。同样,像所有 async 函数一样,它返回其结果的 promise

    async function filterAsync(array, callback, thisArg = undefined) {
        const flags = await Promise.all(array.map(callback, thisArg));
        const result = [];
        for (let n = 0; n < array.length; ++n) {
            if (flags[n]) {
                result.push(array[n]);
            }
        }
        return result;
    }
    

    要使用它,你必须使用承诺:

    // In an `async` function (assuming you want errors to propagate):
    const newArray = await filterAsync(Alerts[symbol], element => /*...keep-or-toss logic...*/);
    // ...use `newArray`...
    

    // Not in an `async` function
    filterAsync(Alerts[symbol], element => /*...keep-or-toss logic...*/)
    .then(newArray => {
        // ...use `newArray`...
    })
    .catch(error => {
        // ...handle/report error...
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-18
      • 1970-01-01
      • 2014-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多