猿问

.some()函数使用async和await总是返回true

我有一个JavaScript类,async里面有一些函数。

如果在这个数组中有一个大于10的数字,我希望.some()函数返回true,但是如果数组不包含大于10的数字,我希望它返回false。

我遇到的问题是函数调用总是返回true数组中是否有大于10的数字。

class Blah {
    async doStuff() {
        const nums = [1, 2, 3, 4, 5, 6];
        const asyncResult = await nums.some(async num => {
            if (num > 10) {
                const allowed = await this.isAllowed(num);
                if (allowed) {
                    return true;
                }
            }
        });
        console.log(asyncResult);
    }
    async isAllowed(num) {
        console.log(`${num} is in the array`);
        return true;
    }}const b = new Blah();b.doStuff(); // This return true but it should be returning false

这当前返回,true但正如您所看到的,数组没有大于的数字10

如果我async.some()函数内部删除它似乎工作,但该函数需要是async因为我需要awaitthis.isAllowed函数调用,这也是一个async函数。


波斯汪
浏览 986回答 3
3回答

慕容森

.some是同步的。当你的函数返回一个promise(就像所有异步函数那样)时,.some将其视为一个truthy值。因此,结果是真的。如果你想让所有的promises解决,然后检查结果,你可以这样做:async doStuff() {   const nums = [1, 2, 3, 4, 5, 6];   const promises = nums.map(async num => {     if (num > 10) {       const allowed = await this.isAllowed(num);       if (allowed) {         return true;       }     }   });   const areAllowed = await Promise.all(promises);   const result = areAllowed.some(val => val);   console.log(result);}如果这些可能是长期运行的承诺,并且您希望能够在任何一个解析为真的时候立即拯救,那么您可以这样做:async doStuff() {   const nums = [1, 2, 3, 4, 5, 6];   const result = await new Promise(resolve => {     let notAllowedCount = 0;     nums.forEach(async num => {       if (num > 10) {         const allowed = await this.isAllowed(num);         if (allowed) {           // Found one that is allowed. Immediately resolve the outer promise           resolve(true);           return;         }       }       // This one isn't allowed       notAllowedCount++;       if (notAllowedCount === nums.length) {         // If we've reached the end, resolve to false. This will only happen         //    if none of the earlier ones resolved it to true.         resolve(false);       }     });   });   console.log(result);}

肥皂起泡泡

像这样的东西应该有帮助(运行代码片段):const isLGTen = async (n) => {  await new Promise(resolve => setTimeout(resolve, 1000));    return n > 10;}const someLGTen = nums => Promise  .all(nums.map(isLGTen))  .then(result => result.some(bool => bool));(async () => {  const data = [1, 2, 3, 4, 5, 11];  console.log(    `is some of "${data}" > "10"?`,     await someLGTen(data),  );})()

拉莫斯之舞

问题:你的some处理程序是一个async函数。异步函数总是返回promises,这被认为是真实的。例如!!new Promise(() => {}) === true。解决方案:相反,你可以使用Promise.all。迭代每个数字,如果任何通过你的条件,解决真实的回报承诺。如果Promise.all完成(即,您已经检查了所有数据)并且尚未解决返回的保证(即没有任何通过您的条件),则解决错误(或拒绝)您的退货承诺。class Blah {  doStuff(nums) {    return new Promise((resolve, reject) => {      let promises = nums.map(async num => {        if (num > 10 && await this.isAllowed(num))          resolve(true);      });      Promise.all(promises).then(() => resolve(false));    });  }  async isAllowed(num) {    console.log(`${num} is in the array`);    return true;  }}const b = new Blah();b.doStuff([1, 2, 3, 4, 5, 6]).then(value => console.log(value));b.doStuff([1, 2, 3, 4, 5, 20]).then(value => console.log(value));
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答