javascript - 修改并返回异步函数内的对象
问题描述
我想userTracker
在异步 js 代码中修改一个对象 ()。运行函数 ( fetchUsers
) 后,我希望在所述对象上有一个更新的字段。undefined
但是我在修改函数中的对象后继续获得。我怎样才能做到这一点?
我的代码:
let userTracker = {
counter : 0,
data : []
}
function fetchUsers(userTracker) {
let filter = {"some" : "conditions"}
User.find(filter).exec() // I am deliberately not calling the `limit()` function. I have a goal to achieve
.then( (users ) => {
return users.forEach((user) => {
if (userTracker.counter < 20) {
userTracker.data.push(user)
userTracker.counter += 1
} else {
return
}
})
})
.catch(err => {
console.log(err)
})
}
fetchUsers(userTracker)
console.log(userTracker) // It logs `{}`. Accessing any field on the object shows `undefined`
运行函数后如何访问填充的userTracker
对象fetchUsers
?我想结束这样的事情
我想要达到的目标:
userTracker = {
counter : 8,
data : [
user1, user2, user3, ...
]
}
我不擅长异步编程,非常感谢任何有关如何实现上述所需输出的帮助。
解决方案
@shivashriganesh-mahato的答案是正确的,但我想解释一下为什么您的原始代码不起作用。
每当您将回调传递给函数时,该函数可能会以以下两种方式之一调用它:(1) 同步或 (2) 异步。同步很容易理解;这意味着回调是在您将回调传递给的函数执行期间执行的。
异步非常不同。回调的执行被推迟,直到当前正在执行的所有同步代码完成。这包括您将回调传递给的函数、包含调用该函数的行的函数等等。回调至少会推迟到整个当前调用堆栈完成执行,之后可能还会更长。例如,当您发送网络请求并传递回调来处理响应时,回调不仅会延迟到调用堆栈清除之后,还会延迟到响应到达之后。从计算机的角度来看,它可能需要很长时间(即几毫秒)。
异步函数调用不会推送到调用堆栈的顶部。相反,它们被放在未来函数调用队列的末尾,每个函数调用都将启动一个自己的新调用堆栈。
您如何捕捉仅在当前调用堆栈展开后才发生的值更改?通过在它之后排队另一个异步函数调用。以下示例代码说明了简单超时的区别:
// sync
let count = 0;
function increment() { ++count; }
function invokesCallbackSync(callback) {
callback();
}
invokesCallbackSync(increment);
console.log(count); // 1
// async
count = 0;
function invokesCallbackAsync(callback) {
setTimeout(callback);
}
invokesCallbackAsync(increment);
console.log(count); // 0
setTimeout(() => console.log(count)); // 1 (eventually)
Promise的.then
方法也调用它的异步回调。好处then
是它总是返回一个新的 Promise,所以你可以在第一个 Promise 完成后排队另一个异步回调,依此类推。因此,使您的代码工作的最小更改如下:
let userTracker = {
counter : 0,
data : []
}
function fetchUsers(userTracker) {
let filter = {"some" : "conditions"}
return User.find(filter).exec()
.then( (users ) => {
return users.forEach((user) => {
if (userTracker.counter < 20) {
userTracker.data.push(user)
userTracker.counter += 1
} else {
return
}
})
})
.catch(err => {
console.log(err)
})
}
fetchUsers(userTracker).then(() => console.log(userTracker))
推荐阅读
- python - 熊猫日期发生变化时如何减去时间?
- angular - ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改...以前的值:'ngIf:false'。当前值:'ngIf: true'
- math - 球与天花板的碰撞时间
- mercurial - Hg:复制文件而不保存历史记录(复制为新文件)
- python - 为什么在 Windows 10 下启动 python 如此缓慢,以及如何加快速度
- strapi - 如何用strapi纠正nginx conf
- c++ - 为什么 boost::bind 坚持将 `boost::placeholders` 拉入全局命名空间?
- javascript - JavaScript 类:(this 的实例)
- angular - angulartics2 自定义事件被发送到 facebook 但不发送到谷歌分析
- javascript - 第三个框锁定值JS