我很有趣的是,promise.join 如何在 javascript 库中实现而不使用多线程原语(这不是关于浏览器实现(ES6 Promise)的问题)。
例如,让我们看看这段代码 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);
}
可能会发生第一个增量大于第二个增量的情况,只有稍后我们才会检查是否。所以会有两次回调调用。
最佳答案
想象一下,您在 JS 中运行的所有可能对其他代码片段产生副作用的代码默认情况下都是原子的,并且您作为程序员所接触到的一切都是在关键部分。
JavaScript 本身没有并发的概念 - 它依赖外部“主机函数”来实现并发(在浏览器中是 DOM API - 在节点中是节点的 API 或 C++ 模块)。 JS 中的用户代码 - 除非明确告知运行,否则将在单个线程上运行。也就是说,通知程序的代码将一次在一个处理程序上运行。如果有多个异步操作完成 - 它们将在队列中相互等待,并且一次只会执行一个。
关于javascript - Promise 库中的 Promise join 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27217399/