Javascript嵌套For循环在返回数组时不更新数组 let posts=[]; 对于(var i=user.posts.length-1;i>=0;i--){ posts.push(user.posts[i]); } for(var i=0;i0){ 对于(var j=theuser.posts.length-1;j>=0;j--){ posts.push(用户posts[j]); } } } }); } 返回岗位;
所以我的问题是,当我调用这个函数时,posts没有正确返回。当我运行这个程序时,我想返回一个posts数组,第一个for循环运行良好,但是当我想将元素从var=j的nest for循环推送到数组中时,它不会更新posts数组。我认为这可能与异步函数有关,但我不确定如何在我的例子中实现它;至少不像你现在这样Javascript嵌套For循环在返回数组时不更新数组 let posts=[]; 对于(var i=user.posts.length-1;i>=0;i--){ posts.push(user.posts[i]); } for(var i=0;i0){ 对于(var j=theuser.posts.length-1;j>=0;j--){ posts.push(用户posts[j]); } } } }); } 返回岗位;,javascript,node.js,asynchronous,async-await,nested,Javascript,Node.js,Asynchronous,Async Await,Nested,所以我的问题是,当我调用这个函数时,posts没有正确返回。当我运行这个程序时,我想返回一个posts数组,第一个for循环运行良好,但是当我想将元素从var=j的nest for循环推送到数组中时,它不会更新posts数组。我认为这可能与异步函数有关,但我不确定如何在我的例子中实现它;至少不像你现在这样 let posts = []; for(var i = user.posts.length - 1; i >= 0; i--){ posts.push(user.posts[i]);
let posts = [];
for(var i = user.posts.length - 1; i >= 0; i--){
posts.push(user.posts[i]);
}
for(var i = 0; i < user.friends.length; i++){
let query = {username:user.friends[i]};
User.findOne(query, function(err, theuser){
if(err) throw err;
if(theuser){
if(theuser.posts.length > 0){
for(var j = theuser.posts.length - 1; j >= 0; j--){
posts.push(theuser.posts[j]);
}
}
}
});
}
return posts;
另一种选择是async
/wait
。在这里,我们也使用而不是手工重写findOne
// reverse copy of user posts
const posts =
[ ...user.posts ].reverse()
// "promisified" findOne
const findOne = query =>
User.findOne
( query
, (err, res) =>
err
? Promise.reject(err)
: Promise.resolve(res)
)
Promise
.all(user.friends.map(username => findOne({ username }))
.map(friend => friend.posts.reverse())
.then(friendPosts => posts.concat(friendPosts)
.then
( allPosts =>
// do something with all posts here
)
其中每个节点都有一个类似于/0
、/1
等的路径,并且节点可以使用\u link
属性链接到其他节点。链环->链环->链环链的长度不受限制。给定一个起始节点,目标是生成整个节点序列——
const DB =
{ '/0': { a: 'a', _link: '/1' }
, '/1': { b: 'b', _link: '/2' }
, '/2': { c: 'c', d: 'd', _link: '/3' }
, '/3': { e: 'e' }
, '/4': { f: 'f', _link: '/5' }
, '/5': { g: 'g' }
// ...
}
我们需要一些方法来定义一个循环,一些方法来初始化它,一些方法来执行下一个循环,最后一些方法来说明循环何时完成。哦,所有的东西都必须是异步的
这是一项艰巨的任务,但是async
和wait
可以胜任这项任务。在编写泛型函数时,我们尽可能保持泛型,以最大限度地提高可重用性-
recursiveGet ('/0') .then (console.log, console.error)
// [ { a: 'a' }, { b: 'b' }, { c: 'c', d: 'd' }, { e: 'e' } ]
recursiveGet ('/4') .then (console.log, console.error)
// [ { f: 'f' }, { g: 'g' } ]
recursiveGet ('/99') .then (console.log, console.error)
// Error: path not found: /99
给定一个不执行递归查询的get
函数-
const asyncUnfold = async (loop, init) =>
// call the user's loop with
loop
// the "next" function
// accepts two arguments
// 1. the item to add to the result
// 2. the next accumulator
( async (x, acc) =>
// the item is prepended to the recursive result
[ x, ...await asyncUnfold (f, acc) ]
// the "done" function
// accepts one argument
// 1. then final item of the result
, async (x) => [ x ]
// initial accumulator
, init
)
我们现在可以使用asyncUnfold
-
const get = async (url = '') =>
fetch (url) .then (res => res .json ())
无需触摸承诺
,拒绝
,解决
,或然后
。我希望这能让您大致了解一下使用async
和wait
可以生成的功能强大的表达式。在下面的浏览器中验证结果-
const asyncUnfold=async(f,init)=>
f(异步(x,acc)=>[x,…等待异步展开(f,acc)]
,异步(x)=>[x]
,init
)
const get=async(url='')=>
fetch(url).then(res=>res.json())
const recursiveGet=async(initUrl)=>
异步展开
(异步(下一步,完成,{u链接,{res})=>
_链接
?下一步(res,等待获取(_链接))
:完成(res)
,等待获取(initUrl)
)
常数DB=
{'/0':{a:'a',_链接:'/1'}
,'/1':{b:'b',_链接:'/2'}
,“/2”:{c:'c',d:'d',_链接:'/3'}
,'/3':{e:'e'}
,'/4':{f:'f',_链接:'/5'}
,'/5':{g:'g'}
}
//假抓取用于演示
常量获取=(url=“”)=>
DB[url]==未定义
? 拒绝(错误(`path not found:${url}`)。然后(延迟)
:Promise.resolve({json:()=>DB[url]})。然后(延迟)
//假延迟演示
常数延迟=(x,ms=250)=>
新承诺(r=>setTimeout(r,ms,x))
recursiveGet('/0')。然后(console.log,console.error)
//[{a:'a'},{b:'b'},{c:'c',d:'d'},{e:'e'}]
我看不出你的代码有任何明显的错误。它可能有助于了解您是如何测试代码的,以及您看到的返回值与期望值之间的差异。为什么将此标记为async
/await
?使用承诺计划吗?。findOne()
是异步的<代码>返回帖子在帖子之前执行。按(…)
。
const asyncUnfold = async (loop, init) =>
// call the user's loop with
loop
// the "next" function
// accepts two arguments
// 1. the item to add to the result
// 2. the next accumulator
( async (x, acc) =>
// the item is prepended to the recursive result
[ x, ...await asyncUnfold (f, acc) ]
// the "done" function
// accepts one argument
// 1. then final item of the result
, async (x) => [ x ]
// initial accumulator
, init
)
const get = async (url = '') =>
fetch (url) .then (res => res .json ())
const recursiveGet = async (initUrl) =>
// use our new magic wand
asyncUnfold
// our loop
// receives 3 arguments
// 1. the "next" function
// 2. the "done" function
// 3. the accumulator
( async (next, done, { _link, ...res }) =>
// if we have a _link ...
_link
// add res to the output
// the next step is get(_link)
? next (res, await get (_link))
// otherwise there is no _link
// call done with the last result
: done (res)
// initial accumulator
, await get (initUrl)
)