簡體   English   中英

如何在JS(節點)中使用回調來等待Async函數完成才能繼續?

[英]How to use callback in JS (node) to wait for Async function to finish before proceeding?

我有一個名為translateCommand(command)的函數,該函數使用npm中的Translate包將一些文本翻譯成另一種語言。 問題在於該包提供的轉換函數是異步的,並且它傾向於在轉換函數完成之前退出translateCommand函數,從而導致垃圾數據的返回。

我發現問題的解決速度太快了,並且將translateCommand(command)設為異步函數,以便可以在導入的translate()函數之前使用await,從而解決了該問題,但是現在我只是延遲了一個問題向后退一步,因為調用translateCommand(command)的函數遇到了完全相同的問題,並且我覺得如果我不得不繼續向上重復此鏈,我似乎沒有取得任何進展。

事實是,我不太了解Promises以及Async函數相對於它們的一般行為。 我意識到這是使Node.js變得更好的前提,但是嘗試了解它卻沒有效果。 嘗試解決此問題並沒有真正取得成果,因為每個人都只是說使用回調而沒有解釋確切的回調是什么。 這些示例通常被陌生的代碼包圍着,這無濟於事,因此我認為在代碼的上下文中獲得幫助將用兩只石頭解決兩只鳥。

這是我做一個愚蠢的Discord Bot的介紹性嘗試,我在其中實現了許多愚蠢的功能。 我已經遇到過Async牆很多次了,但通常會找到一個Synchronous替代方法來繼續前進。 這次我沒有這樣做,我嘗試模擬其他Stack Overflow帖子中描述的回調,但是由於缺乏理解,因此無法正確集成它們(我只能假設)。

頂級導入的函數現在有異步問題。

client.on("message", (message) => {

    // ...
    let command = (message.content).substr(1);

    // ...

    // Handles translate command
    else if (command.startsWith("translate"))
        message.channel.send(translateCommand(command));

    // ...
    }
});

已異步執行的功能,因此可以等待:

// Form !translate [string]
async function translateCommand(command) {
    let message = "";
    let str = command.substr(10);

    await translate(str, { to: 'ja', engine: 'yandex', key: '<my key>' }).then(function(result) {
        message = result;
        return "";
    });
    return message;
}

我知道這個問題已經死了,但是我覺得如果沒有上下文,我就會理解(因為我仍然對JS和Node還是陌生的),我只能將頭撞在牆上,直到有些事情無法解決為止了解原因。

您也可以將頂級功能更改為異步。 將開頭更改為async (message) => {並使用message.channel.send(await translateCommand(command)) 或者,您可以選擇使用Promise而不是使函數異步,而是使用translateCommand(command).then(msg => message.channel.send(msg)) ,但是稍后可能會擾亂流程。

因為translate返回了promise,所以您無需使translateCommand async 只需從函數返回translate ...

function translateCommand(command) {
  let str = command.substr(10);
  return translate(str, { to: 'ja', engine: 'yandex', key: '<my key>' });
}

...並await解決的諾言。 您需要向事件處理程序回調添加async ,以await工作。

client.on("message", async (message) => {

  let command = (message.content).substr(1);

  //...

  else if (command.startsWith("translate"))
    message.channel.send(await translateCommand(command));
    // ...
  }
});

使用promise,您可以執行以下操作:

translateCommand函數:

var translateCommand = (command) => new Promise((resolve,reject) =>  {
    translate(command.substr(10), { to: 'ja', engine: 'yandex', key: '<my key>' })
        .then(resolve)
        .catch(reject)
    });

然后client.on

client.on("message", (message) => {

    // ...
    let command = (message.content).substr(1);

    // ...

    // Handles translate command
    else if (command.startsWith("translate"))
        translateCommand(command)
            .then(translationResult => {
               message.channel.send(translationResult)
            })
    // ...
    }
});

如果您在語法上遇到麻煩,請參考以下提示:
提示#1
提示#2
+一句話-不要害怕,花時間閱讀+實施上述示例,然后對其進行修改,以引起錯誤(您將知道它們何時以及如何起作用或不起作用-痛苦但有回報;))

暫無
暫無

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

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