我与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)
将是异步。 可能会采取上面的例子添加完成者/将来如果可以使异步帮我明白了。
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()
不一定会阻塞。