在镖异步编程(async programming in dart)

2019-07-04 01:46发布

我与Java作为要怎么做线程/异步。 我使用新主题(目标)。开始(),其中目标是可执行的,做线程在Java中的一种方式。 新并发API有办法,但我们知道,在特定的呼叫新线程的创建和任务通过被执行。

同样如何在达特异步做了什么? 我读发送/ receivport,完成者/未来,spawnFunction。 对我来说,只有spawnFunction是有说服力的语句,将创建新的线程。 一个可以解释如何完成者/未来帮助。 我知道他们需要回调,但有没有在JavaScript中一些隐含的逻辑/规则/镖是回调总是在不同的线程中执行。

下面是镖片断/伪代码:

void callback() {
  print("callback called");
}

costlyQuery(sql, void f()) {
  executeSql(sql);
  f();
}

costlyQuery("select * from dual", callback);

我希望我的costlyQuery签名采取功能第二个参数是正确的。 所以现在我不认为f()executeSql(sql)将是异步。 可能会采取上面的例子添加完成者/将来如果可以使异步帮我明白了。

Answer 1:

TL;博士 :有一个回调不会阻止任何隐含规则。

JavaScript事件队列

在Javascript中,没有线程(除WebWorkers,但这是不同的)。 这意味着,如果你的代码块的任何部分,整个应用程序被阻止。 没有什么神奇的约回调,也只是功能:

function longLoop(cb) {
    var i = 1000000;
    while (i--) ;
    cb();
}

function callback() {
    console.log("Hello world");
}

function fun() {
    longLoop(callback);
    console.log("Called after Hello World is printed");
}

为了使一些异步,回调必须放在事件队列中,只通过一些API调用发生的情况:

  • 用户发起的事件handlers-点击,键盘,鼠标
  • API事件handlers- XMLHttpRequest的回调,WebWorker通信
  • 定时职能 - 的setTimeout,setInterval的

当触发事件,回调被放置在事件队列时,所有其他的回调已经完成执行执行。 这意味着你的代码的任何两条线都不会在同一时间被执行。

期货

我假设你已经至少无意中发现了这个帖子关于期货 。 如果不是,它是一个很好的读取和直接从马口来了。

在Javascript中,你必须做一些工作,使异步代码感。 甚至还有一个Javascript库称为期货做普通的东西,比如异步循环和序列(全面披露,我曾亲自与此库的工作的作者)。

未来的概念是由函数创造未来,未来将在某个时候在路上完成做出了承诺。 如果您打算做一些异步调用,开创未来,归还,并履行承诺时,异步调用完成。 从博客文章:

Future<Results> costlyQuery() {
    var completer = new Completer();

    database.query("SELECT * FROM giant_table", (results) {
        // when complete
        completer.complete(results);
    });

    // this returns essentially immediately,
    // before query is finished
    return completer.future; 
}

如果database.query是一个阻塞调用,未来将立即完成。 本例假设database.query是非阻塞的调用(异步),所以未来将这个函数退出后得到满足。 completer.complete将调用什么功能是传递给completer.then()与指定的参数。

你的榜样,修改为成语和异步:

void callback() {
  print("callback called");
}

costlyQuery(sql) {
  var completer = new Completer();
  executeSql(sql, () => completer.complete());
  return completer.future;
}

costlyQuery("select * from dual").then(callback);

这是异步的,正确地使用期货。 你可以通过你自己的回调函数到costlyQuery为你做,并呼吁,在回调executeSql来达到同样的事情,但毕竟是做,而不是飞镖方式的JavaScript的方式。

分离

分离株类似于Java的线程,但分离是一个并发模型和线程并行度模型(参见这太问题有关并发VS并行的更多信息)。

飞镖是特殊的,该规范并没有强制要求一切都在一个单独的线程中运行。 它只强制要求,不同的执行上下文没有访问相同的数据。 每个隔离都有它自己的内存,只能沟通(如发送数据)与其他菌株通过发送/接收端口。

这些端口的工作方式类似于围棋频道,如果你熟悉的。

的分离物是独立于其他代码运行的分离的执行上下文。 在Javascript中,这意味着它有它自己的事件队列。 见达特旅游更完整的介绍株。

比方说你的ExecuteSQL是阻塞函数。 如果我们不想等待它完成,我们可以把它加载到一个分离:

void callback() {
    print("callback called");
}

void costlyQuery() {
    port.receive((sql, reply) {
        executeSql(sql);
        reply.send();
    });
}

main() {
    var sendPort = spawnFunction(costlyQuery);

    // .call does all the magic needed to communicate both directions
    sendPort.call("select * from dual").then(callback);

    print("Called before executeSql finishes");
}

此代码创建一个分离,将数据发送给其进行注册时,它的完成回调。 即使executeSql块, main()不一定会阻塞。



文章来源: async programming in dart