簡體   English   中英

如何在功能中擺脫異步?

[英]How to get rid of async in function?

假設我有這段代碼:

const myFunction = async => {
  const result = await foobar()
}

const foobar = async () => {
  const result = {}
  result.foo = await foo()
  result.bar = await bar()
  return result
}

我想要這個:

const myFunction = () => {
  const result = foobar()
}

我試着像這樣包裹foob​​ar

const foobar = async () => {
  return (async () => {
    const result = {}
    result.foo = await foo()
    result.bar = await bar()
    return result
  })()
}

但這仍然是一個承諾

我不能在myFunction中使用.then ,我需要foob​​ar返回結果變量而不是promise。

問題是myFunction是一個異步函數,它將返回一個promise但它應該返回undefine我需要擺脫myFunction中的異步。

編輯:正如Sebastian Speitel所說,我想將myFunction轉換為同步

編輯2:到Shilly,我使​​用nightwatch進行end2end測試,nightwatch將調用myFunction()如果執行函數沒有錯誤它將完美運行,如果有錯誤,那么nightwatch的虛擬機將永遠運行而不是停止,如果被調用的函數是異步的,則會出現此問題。

要將異步函數更改為普通的同步函數,您只需刪除async關鍵字,因此所有await該函數中的關鍵字。

const myFunction = async () => {
    const result = await foobar();
    // ...
    return 'value';
};

// becomes

const myFunction = () => {
    const result = foobar();
    // ...
    return 'value';
};

但是,您應該記住一個簡單的規則。

  1. 如果返回值取決於已解析的promise(s)的值,​​則無法將異步函數更改為同步函數。

這意味着處理其體內promises的函數,但返回值不依賴於那些已解析的promises的函數完全可以作為同步函數。 在大多數其他方案中,您無法刪除異步行為。

以下代碼為您提供了一個示例,假設myFunction的返回值不依賴於已解析的promise。

const myFunction = () => {
    const result = foobar();

    result.then(data => doSomethingElse(data))
          .catch(error => console.error(error));

    return 'some value not dependent on the promise result';
};

如果您想了解有關promises的更多信息,我建議您查看promises指南async / await頁面。

您是否考慮過使用.executeAsync()然后讓promise調用.done()回調? 這樣就可以包裝foobar並在該包裝器中保持異步或任何.then()調用。

我的夜班知識非常陳舊,但可能是這樣的:

() => {
  client.executeAsync(( data, done ) => {
    const result = await foobar();
    done( result );
  });
};

要么:

  () => {
    client.executeAsync(( data, done ) => foobar().then( result => done( result )));
  };

任何標記為async函數都將返回Promise。 這個:

const foobar = async () => {
  return 7;
}

將返回7的Promise。這完全獨立於調用foobar的函數是否async ,或者在調用它時使用await與否。

所以,你的問題不是(僅)與myFunction :使用async foobar強制它總是返回一個Promise。

現在,說, 你可能無法實現你想要的 Async-Await 只是promises的語法糖 你正在嘗試從異步操作返回一個同步值 ,這在javascript中基本上是禁止的。

您在此處缺少對代碼的同步和異步性質的非常重要的理解。

並非每個異步函數都可以轉換為同步函數。 您可以使用回調模式而不是await / async,但我懷疑這對您有用。

相反,我建議您只使用await ,就像在第一個代碼示例中一樣,並將函數保留為異步,它不應該損害您的邏輯。

看一下這個

    function foo(){
      return 'foo'
    }
    function bar(){
      return 'bar'
    }
    const foobar = () => {
        return new Promise((resolve)=>{
          let result = {}
          result.foo = foo()
          result.bar = bar()
          return resolve(result)
        })
    }

    const myFunction = () => {
      const result = foobar()
      let response = {}
      result.then(val=>{
        response = Object.assign({}, val);
        return response
      });
    }

    var test = myFunction()
    console.log(test)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM