具体来说,我正在使用Mongoose和Node,但我想这是一个关于异步编码的更具概念性的问题。
我在Mongoose文档中看到了这个例子:
product.sold = Date.now();
product.save(function (err, product, numberAffected) {
if (err) ..
})
然而,如果
product.save(...)
执行得比
快product.sold = Date.now()
在更新之前,你不会保存......? 也许我在这里遗漏了一些东西(在概念层面)?是什么让这段代码在异步环境中保持“安全”。
更具体地说,我正在使用 doc.addToSet 作为“更新”步骤,如果它有回调我会感觉好多了我可以嵌入 doc.save 介入(确保异步行为)。想法?
PS。我不是简单地使用 model.update 因为我需要验证。
答案 0 :(得分:1)
异步并不意味着每条线都会同时执行。在这种情况下,product.sold将被分配并完成,就像正常操作一样,然后保存将在之后顺序调用。
异步部分与product.save一起发生。发生的事情是你将一个函数作为参数传递给product.save,它也是一个函数。这称为匿名回调。它没有名称,并且从product.save内部异步调用。
以下是如何订购执行:
callback.call(...)
,然后product.save返回因此,您更新产品并成功保存。您传递的匿名函数不是实际保存的函数,而是实现您想要的异步扩展,即处理错误或确保保存正确数量的项目。
答案 1 :(得分:0)
您不必担心在保存之前发生更新操作,因为它正在阻止。
要了解阻塞(同步)和非阻塞(异步)操作之间的区别,请使用此基本异步代码:
function async(callback) {
process.nextTick(callback);
}
async(function() {
console.log('foo');
}
console.log('bar');
这将按顺序显示bar
,然后foo
。这里的关键是函数process.nextTick(cb)
,它将延迟回调的执行。
由于NodeJS只使用一个线程,它将等待整个函数堆栈返回,然后在进程的下一个循环中执行回调。现在,如果您的更新操作是异步的,则必须在传递给该操作的回调函数中执行保存操作。
但是,由于它不是(您可以从doc中看到,并且通常,该函数不接受任何回调参数的事实是一个很好的指示),该函数的执行将被阻止,直到该更新操作回报。