2016-09-03 2 views
1
에서 기다리고

I가 예상대로 작동 다음과 같은 기능 :비동기은 대해 forEach

:

createObjectFrom(record) { 
    let obj = {}; 

    this.opts.transformers.forEach((transformer, index) => { 
     const headerIndex = findIndex(this.headers, (header) => { 
     return header === transformer.column; 
     }); 

     const value = transformer.formatter(record[headerIndex]); 

     obj[transformer.field] = value; 
    }); 

    return obj; 
    } 

이 같은 foreach는 본문에 비동기 기능을 비동기 기다리고 있습니다를 사용하여 전화를 리팩토링 할

createObjectFrom(record) { 
    let obj = {}; 

    this.opts.transformers.forEach(async (transformer, index) => { 
     const headerIndex = findIndex(this.headers, (header) => { 
     return header === transformer.column; 
     }); 

     const result = await this.knex('managers').select('name') 

     console.log(result); 

     const value = transformer.formatter(record[headerIndex]); 

     obj[transformer.field] = value; 
    }); 

    return obj; 
    } 

forEach가 이제 비동기 적으로 실행되고 함수가 방금 실행되고 떠날 때 함수가 중단됩니다.

동기식으로 forEach를 실행하려면 async를 사용할 수있는 방법이 있습니까? 내가 발전기를 리팩터링 할 수 있을까?

+0

"forEach가 이제 비동기 적으로 실행될 때마다 기능이 중단됩니다."--- 아무 것도 변경되지 않습니다. 'Array.prototype.forEach'는'async' 함수를 받아 들일 것으로 기대하지 않기 때문에, "async"함수를 "normal"함수로 호출 할 것입니다. 그래서 모든 기능이 즉시 호출됩니다. – zerkms

+0

"forEach가 동기식으로 실행되도록 비동기를 사용할 수있는 방법이 있습니까? --- 단지 for 또는 for-of' 루프를 사용하여 배열을 반복합니다. 또한'createObjectFrom'을'async'로 변경해야합니다. – zerkms

+0

[this one] (https://github.com/toniov/p-iteration)을 사용하면 이런 종류의 물건을 부드럽게 처리 할 수 ​​있습니다. 모듈을 사용해도 상관 없으면 사용해보십시오. –

답변

1

비동기 동작을 기다리는 일반 JS 함수를 적용 할 수 없습니다. 방법이 없다!

따라서 createObjectFrom도 비동기로 리팩터링해야합니다. 그리고 나서 forEach 대신 map/reduce를 사용하십시오. 는이 작업을 수행하지 않으 확대됨에 예정 :

for(transformer of this.opts.transformers) { 
    await this.knex('managers').select('name'); 
} 

대신 당신은 await Promise.all(...)를 사용해야합니다. 당신이 비동기 각 항목 뭔가를 가져처럼 그것을 할 그런 짓을하려는 경우에는

async createObjectFrom(record) { 
    let obj = {}; 

    const result = await this.knex('managers').select('name') 

    this.opts.transformers.forEach(async (transformer, index) => { 
    const headerIndex = findIndex(this.headers, (header) => { 
     return header === transformer.column; 
    }); 

    console.log(result); 

    const value = transformer.formatter(record[headerIndex]); 

    obj[transformer.field] = value; 
    }); 

    return obj; 
} 

:이 작업을 수행 할 수 있도록

그러나 귀하의 경우 knex에 대한 호출은 변압기에 의존하지 않는 것 같다 이 :

async foo(data) { 
    const subDataArr = await Promise.all(data.map(record => loadSubData(record))); 

    return subDataArr; 
} 
+0

foreach를 반복 할 때마다 knex 호출이 필요합니다. 그것은 매우 일반적인 사용 케이스 노드에서 처리하는 방법이 궁금하다. – dagda1

+0

@ dagda1 thats 기본적으로 내 마지막 코드 예제. 'loadSubData'가 Knex 호출이라고 가정합니다. – Lux