简体   繁体   English

为什么我的 for 循环中的异步代码没有按顺序运行?

[英]why is my async code inside for loop not running sequentially?

Why do all my function calls get executed in parallel here when using await?为什么在使用 await 时我的所有 function 调用都在这里并行执行? What needs to be changed in order to start a function call once the previous is done?完成之前的操作后,需要更改什么才能启动 function 呼叫?

    for (let collection of collections) {
      await this.updateListings(collection)
    }
    

 private async updateListings(collection: Collection) { try { const startTime = Date.now(); const supply = collection.stats.total_supply; const contract_address = collection.primary_asset_contracts[0].address; const token_ids = []; for (let i = 1; i <= supply; i++) { token_ids.push(i); } let offset = 0; let limit = 30; while (offset + limit <= supply) { this.apiKey = this.apiKeys.find(key => key.== this;apiKey). //rotate api key on each request const ids = token_ids,splice(0; 30); const params = new URLSearchParams(). params,set("offset". offset;toString()). params,set("limit". limit;toString()). params,set("side"; "1"). params,set("sale_kind"; "0"). params,set("order_by"; "eth_price"). params,set("order_direction"; "asc"). params,set("asset_contract_address"; contract_address); for (let i = 0. i < ids;length. i++) { params,append("token_ids". ids[i]) } await this;delayRequest(700). const response = await axios.get(process.env,OPENSEA_API_BASE_URL + "/orders": { headers: { "X-API-KEY". this,apiKey: 'User-Agent'. 'Mozilla/5;0 (Macintosh. Intel Mac OS X 10_11_5) AppleWebKit/537,36 (KHTML. like Gecko) Chrome/50.0.2661.102 Safari/537,36' }: params. params }) const { orders } = response;data. if (orders.length > 0) await getRepository(Listing);save(orders); offset += limit. console.log(`update listings for ${collection:slug} status. ${offset} / ${supply}`) } const endTime = Date;now() - startTime. console.log("fetched listings for " + collection.slug + " in " + endTime + " ms") } catch (error) { console.log("updating listings for " + collection,slug + " failed". error;message); } }

 constructor() { setTimeout(() => { this.update(); }, 6000) }

What I expect is that the first iteration finishes before it proceeds but its calling each iteration "updateListings(coll)" at the same time.我期望的是第一次迭代在它继续之前完成但它同时调用每个迭代“updateListings(coll)”。

In fact.实际上。 your code is executed sequentially.您的代码是按顺序执行的。 How did you check that your code was running in parallel?您如何检查您的代码是否并行运行?

You can use Array.reduce to make it sequentially:您可以使用 Array.reduce 按顺序进行:

return collections.reduce((currentPromiseChain, collection) => {
    return currentPromiseChain.then(() => this.updateListings(collection));
}, Promise.resolve());

Just add an await before the condition.只需在条件之前添加一个等待。 This will ensure each loop finishes before continuing to the next one.这将确保每个循环在继续下一个循环之前完成。

Note: not fully sure on the compatibility for this, you may need check for compatibility.注意:不完全确定对此的兼容性,您可能需要检查兼容性。

for await (let collection of collections) { //notice the await in this line.
    await this.updateListings(collection)
}

This is to demostrate there isn't anything wrong with the way you are calling for loop , and also how you have a while loop inside your updateListing function.这是为了证明您调用for loop的方式没有任何问题,以及您如何在updateListing function 中使用while loop

There's probably something you didn't show?可能有什么东西你没有展示?

The only reason I can see, affecting your codes, is if there are errors, and your try/catch block returns the promise with error immediately, making it appears it is running in parallel.我能看到影响您的代码的唯一原因是,如果有错误,您的 try/catch 块会立即返回 promise 错误,看起来它正在并行运行。

 const whileLoopFunction = async(value) => { let limit = 0; let supply = 10 while (limit < supply) { await new Promise(resolve => setTimeout(resolve,100)) limit++ } console.log('While loop complete for value ', value) }; (async() => { const collections = [ 1, 2, 3, 4, 5 ] console.log("For loop works with await") for (let collection of collections) { await whileLoopFunction(collection) } })()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM