簡體   English   中英

async/await 記錄到控制台但不返回任何值並返回 `Promise { pending }`

[英]async/await logs to the console but returns no value and returns `Promise { pending }`

在過去的幾個小時里,我一直試圖讓這個異步 function 的結果沒有成功。 我檢查了過去類似的問題和解決方案,但對於這個特定案例沒有任何效果。

當我運行 console.log 時,下面的這個特定代碼會記錄該值:

const okay = async () => {
  console.log(await getTimezoneLabel(timezone));
};

okay();

下面的代碼記錄Promise {pending}而不是控制台的值,這令人費解

const okay = async () => {
  return await getTimezoneLabel(timezone);
};

let result = okay();

console.log(result);

這是 getTimezoneLabel function 本身:

async function getTimezoneLabel(timezone) {
  const timezoneObject = await convertTimezone('original', timezone);
  return timezoneObject[0].label;
}

這是 getTimezoneLabel function 引用的 convertTimezone function :

import timezonesList from '../timezone-list';

async function convertTimezone(labelStyle, timezone) {
  const spacetime = (await import('spacetime')).default;
  const soft = (await import('timezone-soft')).default;

  const timezones = Object.fromEntries(Object.entries(timezonesList).filter(([key]) => key.includes(timezone)));

  return Object.entries(timezones)
    .reduce((selectOptions, zone) => {
      const now = spacetime.now(zone[0]);
      const tz = now.timezone();
      const tzStrings = soft(zone[0]);

      let label = '';
      let abbr = now.isDST()
        ? // @ts-expect-error
          tzStrings[0].daylight?.abbr
        : // @ts-expect-error
          tzStrings[0].standard?.abbr;
      let altName = now.isDST() ? tzStrings[0].daylight?.name : tzStrings[0].standard?.name;

      const min = tz.current.offset * 60;
      const hr = `${(min / 60) ^ 0}:` + (min % 60 === 0 ? '00' : Math.abs(min % 60));
      const prefix = `(GMT${hr.includes('-') ? hr : `+${hr}`}) ${zone[1]}`;

      switch (labelStyle) {
        case 'original':
          label = prefix;
          break;
        case 'altName':
          label = `${prefix} ${altName?.length ? `(${altName})` : ''}`;
          break;
        case 'abbrev':
          label = `${prefix} ${abbr?.length < 5 ? `(${abbr})` : ''}`;
          break;
        default:
          label = `${prefix}`;
      }

      selectOptions.push({
        value: tz.name,
        label: label,
        offset: tz.current.offset,
        abbrev: abbr,
        altName: altName,
      });

      return selectOptions;
    }, [])
    .sort((a, b) => a.offset - b.offset);
}

我怎樣才能讓它工作?

非常感謝你。

我在這里簡化了很多,但這有助於理解。 當您將 function 聲明為async時,它所做的就是將 function 包裝在 Promise 中 因此,例如,這個 function:

async function something(){ return "hello world" }

可以讀為:

function something(){
  return new Promise((resolve, reject) => {
    resolve("hello world")
  })
}

簡而言之, Promise 只是安排稍后執行 function(在這種情況下為something )。 因此,我們只能稍后在它准備好時讀取返回的值。 當你調用something()時,它會返回一個Promise ,因為它還沒有被執行(它的執行被擱置在隊列中)。 您可以通過閱讀有關事件循環、調用堆棧和事件隊列的信息來了解有關其工作原理的更多信息。

要獲取 Promise 的返回值,我們使用名為.then((value) => {})的方法,它在變量value中返回 function 的返回值(在我們的例子中,值將包含"hello world" ) . 所以:

let r = something()
console.log(r) // Promise pending
r.then((value) => {
  console.log(value) // "hello world"
})

如果你想使用value ,你將不得不:

  • 將您的代碼放入.then()並在那里繼續
  • 將您的代碼放入異步 function 並在調用前使用await
async function run(){
  let value = await something()
  console.log(value) // "hello world"
  // do things with value
}

run()

異步 function 返回 promise。 試試看:

const okay = async () => {
  return await getTimezoneLabel(timezone);
};

okay().then(result=>console.log(result));

或者,如果您在另一個異步 function 中調用 OK(),則可以使用 await 語法:

// should be inside async function
const result = await okay();

這是一個類似的問題,已經通過一些很好的解釋得到了回答

好吧,基本上異步 function 返回 promise。 您可以在異步 function中使用 use let somevariable = await okay()或者您可以這樣做

okay().then((resp)=>{
   console.log(resp)
})

暫無
暫無

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

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