为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

波斯汪 2019-04-18 22:19:26
我有一个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因为我需要await在this.isAllowed函数调用,这也是一个async函数。
查看完整描述

3 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

.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);}


查看完整回答
反对 回复 2019-05-17
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

像这样的东西应该有帮助(运行代码片段):


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),

  );

})()


查看完整回答
反对 回复 2019-05-17
?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

问题:


你的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));


查看完整回答
反对 回复 2019-05-17
  • 3 回答
  • 0 关注
  • 985 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信