【问题标题】:async await not working properly异步等待无法正常工作
【发布时间】:2018-05-19 20:14:59
【问题描述】:

我是 JavasSript 的 asyncawaitpromise 功能的新手。

我正在做的是,

async function sendTextMessage(text) {
    console.log("----1----");
    var messageData = {
        message: {
            text: text
        }
    };
   await callSendAPI(messageData);
}

async function sendImageMessage(imageUrl) {
    console.log("----2----");
    var messageData = {
        message: {
            url: imageUrl
        }
    };
  await callSendAPI(messageData);
}

async function sendQuickReply(replies) {
    console.log("----3----");
    var messageData = {
        message: {
            text: text,
            quick_replies: replies
        }
    };
   await callSendAPI(messageData);
}
async function callSendAPI(messageData) {
    await request({
        uri: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {
            access_token: config.FB_PAGE_TOKEN
        },
        method: 'POST',
        json: messageData

    }, function(error, response, body) {
        if (!error && response.statusCode == 200) {
            var recipientId = body.recipient_id;
            var messageId = body.message_id;

            if (messageId) {
                console.log("Successfully sent message with id %s to recipient %s",
                    messageId, recipientId);
            } else {
                console.log("Successfully called Send API for recipient %s",
                    recipientId);
            }
        } else {
            console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
        }
    });
}

我在一个 switch 案例中调用这个函数,例如,

async function send(){
     await sendTextMessage(text);
     await sendImageMessage(img);
     await sendQuickReply(replies)  
}
send()

但是虽然响应显示sendImageMessage() 最后是因为当我发送imageUrl 以生成响应时,此功能可能尚未准备好。

【问题讨论】:

  • 你能分享一下你的问题,它有帮助
  • 如果您是新手,请按顺序了解异步编程概念,例如 callbackspromisesasyncawait。否则,您最终可能会感到困惑。
  • callSendAPI函数中调用的请求函数是什么,你能描述一下吗?
  • @PraveenSoni Request 函数将根据它从三个函数中获得的数据生成有效负载,并将其发送到特定的 Facebook 帐户。
  • request fn 是你制作的,还是一些库功能?你也可以发一下吗

标签: javascript node.js asynchronous promise es6-promise


【解决方案1】:

请注意,此答案是针对 the original question 编写的,而不是 OP 之后所做的编辑。


async 函数是异步的。其他功能不会等待。

所以你调用sendTextMessage 调用callSendAPI 然后程序的其余部分继续。

callSendAPI 异步运行。它调用request 并等待request 返回的承诺得到解决。当它解决后,callSendAPI 获取request 的返回值(好吧,如果你捕获了返回值,它会)然后继续下一行(只是没有下一行)。


async / await 不要使异步代码同步。他们只是让它看起来像 inside 声明为 async 的函数,它本身变成异步的。


您可以将三个函数调用放在它们自己的 async 函数中,确保每个函数都返回一个 Promise,然后使用 await 调用这三个函数中的每一个。


另见How do I return the response from an asynchronous call?

【讨论】:

  • @Sven - 自从我回答这个问题以来,OP 已经显着改变了他们的代码。
  • 啊,这就解释了,我的错!
【解决方案2】:

我希望你要做的只是严格地处理一些操作。

这就是 ES6 中存在 async 和 await 的原因。

所以举个例子,可能是这样做A然后做B然后做C或A> B> C

如您所见,最后一个方法 do3 只有 500 毫秒的延迟,但它作为最后一个而不是第一个执行。 如果没有 async 和 await 运算符,它将作为第一个函数执行,这是 JavaScript 执行的默认行为。 Broser 将首先执行同步代码,然后执行异步代码。但不再使用 async 和 await 了:)

你也应该知道,如果你给字符串加上前缀,函数的数量加上await,就会自动转换成promise。

控制台将打印:

'juraj1'
'juraj2'
'juraj3'

这是一个简单的例子:

function do1() {
      return new Promise(resolve => {
          return setTimeout(() => resolve("juraj1"), 3000);
   });
 }
function do2() {
      return new Promise(resolve => {
            return setTimeout(() => resolve("juraj2"), 2000);
  });
 }

function do3() {
      return new Promise(resolve => {
             return setTimeout(() => resolve("juraj3"), 500);
  });
}

async function ForceAsynTOBeSync() {
    const a = await do1();

    console.log(a);

    const b = await do2();

    console.log(b);

    const c = await do3();

    console.log(c);
  }

  ForceAsynTOBeSync();

【讨论】:

  • 问题在请求中
【解决方案3】:

您必须等待 API 调用:

 await callSendAPI(messageData);

因此这些调用的函数也需要asyncawaited 在调用时等等。

【讨论】:

  • 我已经试过了,但还是不行看看编辑后的代码
  • @nikhil await sendTextMessage(text); await sendImageMessage(imgUrl); await sendQuickReply(replies)
  • 等待 callSendAPI,它应该返回一个承诺
  • @praveen 确实如此。 ://
  • 那里看不到任何回报
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 2019-11-03
  • 2020-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多