await

计算机编程中,await是发现于C#5.0、Python3.5中、Hack、Dart以及Kotlin 1.1的一个特性。

在C#中的应用

在C#中,await运算符在异步方法任务中使用,用于在方法的执行过程中插入挂起点,直到所等待的任务完成。await仅可用于由async关键字修饰的异步方法中。[1]

以下异步方法用于从一个URL上下载data数据。

public async Task<int> SumPageSizesAsync(IList<Uri> uris) 
{
    int total = 0;
    foreach (var uri in uris) {
        statusText.Text = string.Format("Found {0} bytes ...", total);
        var data = await new WebClient().DownloadDataTaskAsync(uri);
        total += data.Length;
    }
    statusText.Text = string.Format("Found {0} bytes total", total);
    return total;
}

JavaScript中的使用

JavaScript中的await只能在异步方法(async function)中使用,用于等待一个Promise对象。当await接收到一个Promise对象时,await将等待Promise任务正常完成并返回其结果。若await接收到的不是Promise,await会把该其值转换为已正常处理的Promise,然后等待其工作完成。

function resolveAfter2Seconds(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function f1() {
  var x = await resolveAfter2Seconds(10);
  console.log(x); // 输出10
}
f1();

C++中的使用

C++20草案官方已确认支持 await 功能 (命名为 co_await )。目前,MSVC和clang已支持co_await,gcc 10也添加了对co_await的实验性支持。

#include <future>
#include <iostream>

using namespace std;

future<int> add(int a, int b)
{
    int c = a + b;
    co_return c;
}

future<void> test()
{
    int ret = co_await add(1, 2);
    cout << "return " << ret << endl;
}

int main()
{
    auto fut = test();
    fut.wait();

    return 0;
}

C中的使用

C语言没有对await/async的官方支援。

某些协程库(例如s_task)通过宏定义的方式, 实现了和其他语言类似的 await/async 的强制性语义要求,即:

1. 必须在 async 标注的函数内,才能调用 await;
2. 等待一个标注为 aysnc 的函数,调用该函数时需要加上 await;
#include <stdio.h>
#include "s_task.h"

//定义协程任务需要的栈空间
int g_stack_main[64 * 1024 / sizeof(int)];
int g_stack0[64 * 1024 / sizeof(int)];
int g_stack1[64 * 1024 / sizeof(int)];

void sub_task(__async__, void* arg) {
    int i;
    int n = (int)(size_t)arg;
    for (i = 0; i < 5; ++i) {
        printf("task %d, delay seconds = %d, i = %d\n", n, n, i);
        s_task_msleep(__await__, n * 1000);  //等待一点时间
    }
}

void main_task(__async__, void* arg) {
    int i;

    //创建两个子任务
    s_task_create(g_stack0, sizeof(g_stack0), sub_task, (void*)1);
    s_task_create(g_stack1, sizeof(g_stack1), sub_task, (void*)2);

    for (i = 0; i < 4; ++i) {
        printf("task_main arg = %p, i = %d\n", arg, i);
        s_task_yield(__await__); //主动让出cpu
    }

    //等待子任务结束
    s_task_join(__await__, g_stack0);
    s_task_join(__await__, g_stack1);
}

int main(int argc, char* argv) {

    s_task_init_system();

    //创建一个任务
    s_task_create(g_stack_main, sizeof(g_stack_main), main_task, (void*)(size_t)argc);
    s_task_join(__await__, g_stack_main);
    printf("all task is over\n");
    return 0;
}

参考文献

  1. . [2018-04-20]. (原始内容存档于2018-04-21).
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.