我很有意思如何在不使用多线程原语的情况下在javascript库中实现promise.join(这不是关于浏览器实现(ES6承诺)的问题)。
例如,让我们看看这段代码 https://github.com/stackp/promisejs/blob/master/promise.js#L37
function join(promises) {
var p = new Promise();
var results = [];
if (!promises || !promises.length) {
p.done(results);
return p;
}
var numdone = 0;
var total = promises.length;
function notifier(i) {
return function() {
numdone += 1;
results[i] = Array.prototype.slice.call(arguments);
if (numdone === total) {
p.done(results);
}
};
}
for (var i = 0; i < total; i++) {
promises[i].then(notifier(i));
}
return p;
}
为什么可以写这样的东西:
numdone += 1;
results[i] = Array.prototype.slice.call(arguments);
if (numdone === total) {
p.done(results);
}
可能会发生第一个增量而不是第二个增量,之后我们将检查是否。因此将会有两次回调调用。
答案 0 :(得分:1)
想象一下,你在JS中运行的所有可能对其他代码产生副作用的代码默认情况下都是原子而你作为程序员所暴露的所有是在关键部分。
JavaScript本身没有并发概念 - 它依赖于外部&#34;主机功能&#34;为了做并发(在浏览器中是DOM API - 在节点的节点的API或C ++模块中)。 JS中的用户代码 - 除非明确告知运行否则将在单个线程上运行。那是 - 通知程序的代码将一次在一个处理程序上运行。如果有多个异步操作完成 - 它们将在队列中等待彼此,并且一次只执行一个。