2016-09-11 3 views
0

저는 node.js와 Javascript가 처음인데 객체 배열을 뒤덮는 루프가 있습니다. 특정 조건에서 함수를 호출해야합니다. 그 함수가 for 루프가 node.js에서 기능이 중지 될 때까지 대기합니다.

fucntion foo1(arr){ 
    for(var i=0 ; arr.length>i ; i++){ 
     if(i==8){//or any other condition 
      doAsyncStuff(hits[i])    
     } 
    } 
} 

function doAsyncStuff(item){ 
parser.parseURL(someurl,function(error,result){ 
    item.someprop=result.someprop; 
}) 
} 
문제가, 내가 그 결과를하기 전에 함수가 끝의 대기 할 수없는 것 상관없이 내가 뭘하지

을 완료되지 않은 상태에서 정지 작업 루프 asnyc 않습니다 업데이트가 필요한 항목을 업데이트하지 않습니다. 일반적인 문제이지만 이해할 수있는 해결책이 없습니다. 도움이 될 것입니다. 감사합니다.

+0

읽기 .... – Rayon

+0

콜백, 약속, rxjs :

var Promise = require('bluebird'); // iterates over the array 'arr' and calls fn // Myfn repeatedly, optionally passing an initial. // for the 1st iteration. For subsequent iterations, // the value returned by prev invocation of Myfn is passed. Promise.reduce(arr, Myfn, someInitialValue); function Myfn(prev, item) { //return a value or a promise. } 

여기 감소의 설명서를 참조하십시오. 이 중 누구도 당신을 도울 것입니다. 마지막 단 하나만'for' 루프를 만들 수 있습니다. – smnbbrv

+0

별로 관련이 없지만 오타가 있습니다 : fucntion – Tom

답변

1

루핑과 비동기식 작업은 JS에서 다소 까다 롭습니다. @smnbbrv가 언급 한 라이브러리 중 하나를 사용할 수 있습니다. 그러나 당신도 스스로 할 수 있습니다.이 라이브러리는 어떻게 작동하는지 이해하는 데 도움이 될 수 있습니다.

function foo1(arr) { 
    next(arr, 0) 
} 

function doAsyncStuff(item, cb) { 
    parser.parseURL(someurl, function(error, result) { 
    item.someprop = result.someprop; 
    cb(result); 
    }) 
} 

function next(arr, i) { 
    // Stop when we reach the end of the array. 
    if (i >= arr.length) { 
    return; 
    } 

    if (i == 8) { // or any condition 
    // Move to the next item only when the async work is done. 
    doAsyncStuff(arr[i], function() { 
     next(arr, i + 1) 
    }) 
    } else { 
    next(arr, i + 1) 
    } 
} 
0

내가 제대로 이해한다면 당신은 reduce (도 작동 것 for 루프)이

function doAsyncStuff(item) { 
 
    return new Promise(resolve => { 
 
    const time = Math.ceil(Math.random() * 2000 + 1000); 
 
    window.setTimeout(() => { 
 
     item.someprop = time; 
 
     resolve(); 
 
    }, time); 
 
    }); 
 
} 
 

 
function foo1(arr) { 
 
    return arr.reduce(
 
    (promise, item, index) => index % 2 === 0 ? promise.then(() => doAsyncStuff(item)) : promise, 
 
    Promise.resolve() 
 
); 
 
} 
 

 
const hits = new Array(9).fill().map(() => ({})); 
 
foo1(hits).then(() => { 
 
    console.log(hits); 
 
});

가되어 같은 것을 사용하여 직렬화 Promise 체인을 사용할 수 있습니다 또한 Promise.all을 사용할 수 있습니다. (얼마나 훌륭한 지 모르겠지만 나는 자주 Promise 사용자가 아닙니다.)

업데이트 : Promise.all

function doAsyncStuff(item) { 
 
    return new Promise(resolve => { 
 
    const time = Math.ceil(Math.random() * 2000 + 1000); 
 
    window.setTimeout(() => { 
 
     item.someprop = time; 
 
     resolve(); 
 
    }, time); 
 
    }); 
 
} 
 

 
function foo1(arr) { 
 
    return Promise.all(
 
    arr.map((item, index) => index % 2 === 0 && doAsyncStuff(item)) 
 
); 
 
} 
 

 
const hits = new Array(9).fill().map(() => ({})); 
 
foo1(hits).then(() => { 
 
    console.log(hits); 
 
});

사용이 아직도 ES6를 포맷하는 가장 좋은 방법을 생각하지 않은, 항상 기름 한 라인으로 끝날 것으로 보인다. (개인 스타일링 문제) :)

관련 문제