2016-09-28 2 views
3

객체를 푸시 (push)하는 배열이 있는데 배열의 처음에 객체를 추가하려면 array.unshift(object)을 사용하고 있습니다.unshift 및 pop 시퀀스를 사용하는 객체 배열 처리

배열 끝에있는 객체를 제거하고있는 var object = array.pop()을 사용하여 배열에서 요소를 가져옵니다.

이제 내 배열이 매우 빠르게 채워지고 있습니다.이 배열의 여러 객체가 매초마다 푸시됩니다. 새 요소가 배열에 푸시 될 때마다 배열을 팝하여 처리하고 추가로 보내야합니다. 시간이 걸립니다.

매번 1 초 간격으로 메소드를 호출 한 다음 배열에서 하나의 요소를 팝하여 처리하는 것이 좋은 방법이지만, 배열에서 객체를 처리하는 데 1 초 이상 걸리면 프로세스 메서드에 대한 다음 호출도 지연되어야합니다. 짧은 프로세스 배열 메서드는 모든 간격 후에 호출되어야하지만 이전 호출이 아직 처리 중이면 기다려야합니다.

더 나은 구현 방법은 무엇입니까?

샘플 코드는 : 당신이 큐를 구현 같은

angular.module('myApp') 
.service('DataService', ['$rootScope', 'UpdateService', function($rootScope, UpdateService) 
{ 
    // To store array of JSON updates  
    var arrayOfUpdates = []; 

    // To store callbacks to which we need to send updates after processing 
    var arrayofCallbacks = []; 

    // Method is getting called when there are updates from "UpdateService" server 
    this.onDataUpdated = function (jsonObj) 
    { 
     // This will add this object in the array 
     arrayOfUpdates.unshift(jsonObj); 
    } 

    // This method will process data and send it further 
    function processData() 
    { 
     // Get the last element from the array 
     var jsonObj = arrayOfUpdates.pop(); 

     // Now process this JSON data 
     var data = doSomeCalculations(jsonObj); 

     // There can be 10-20 callbacks at a time 
     for(var index=0;index<arrayofCallbacks.length;index++) 
     { 
       var object = arrayofCallbacks[index]; 
       object.onUpdatedData(data); 
     }  

     // After this pop next element and process and send to registered callbacks 
     // I can not call "processData()" again as it can create loop 
     // Also calling it after interval might call it when it has not completed processing 
    } 
}); 
+0

약속하셨습니까? – cracker

+1

조금 더 자세히 설명해 주시겠습니까? 이 배열은 어떻게 채워 집니까? 어떤 유형의 가공을하고 있습니까? 좀 더 구체적 일수록 도움이됩니다. 또한 더 많은 코드를 추가 할 수 있다면 도움이 될 것입니다 – wilsotobianco

+0

왜 다음 항목을 처리하기 전에 잠깐 기다려야합니까? –

답변

1

그것은 나에게 보인다. 대기열 (unshift)의 뒤쪽으로 밀어 넣을 수 있기를 원하면이 작업은 매우 빠르게 발생할 수 있습니다. 대기열 (pop) 앞에있는 항목을 처리하려고하지만 처리 단계에 시간이 걸립니다. 내 생각 엔이 프로세스가 비동기 적으로 작동한다는 것입니다. 따라서 동시에 발생하는 많은 처리 단계로 끝나고 데이터와 함께 몇 가지 인종과 마주 치게됩니다.

대기열에있는 내용 (처리 기능 제외)을 적극적으로 확인하지 않는 한, 대기열을 모두 제거하고 대기열 대신 약속 체인을 사용하는 것이 좋습니다.

unshift() 대신에 들어오는 데이터 이벤트가 트리거 될 때마다 이전의 모든 처리가 완료 될 때까지 실행되지 않는 약속 체인에 데이터를 전달하기 만하면됩니다. 일부 의사 JS :

// the promise chain (initialised to automatically trigger then()) 
var worker = Promise.resolve(); 

// handle incoming data 
function incomingData(data){ 
    // process this data AFTER all other processing and update the chain 
    worker = worker.then(last => processData(data)); 
} 

// process data 
function processData(data){ 
    // do work on the data and return a promise if work is async 
    return ... 
} 

업데이트 : 제안 제일 먼저 Promises에 독서 될 것이다. 하지만 아래에서 좀 더 깊이있는 설명을 드리겠습니다.

  1. 작업자를 설정하십시오. 변수를 Promise.resolve()으로 설정하면 본질적으로 이미 해결 된 (완료된) 약속이 생성됩니다. 이 작업을 수행해야하는 모든 작업을 완료 한 빈 대기열이라고 생각하십시오.

  2. 새로운 수신 데이터를 얻으면 약속 체인을 업데이트하십시오. 그 안에 함수를 넣으면 myPromise.then(myFunc)처럼 myFunc는 myPromise이 해결 될 때까지 실행되지 않습니다. 이는 프로그래머에게 달려 있습니다. 일부 API 호출이 반환되었거나 다른 작업 후 해결 될 수 있습니다. 다음과 같이 작업자에 대한 업데이트를 생각해 볼 수 있습니다. processData(data)data을 전달할 때마다 processData(data)이 실행될 때마다 새로운 데이터가 도착할 때를 상상해보십시오. 이제는 이전 작업이 완료 될 때까지 함수를 실행할 수 없다고 상상해보십시오. 위의 코드에서 이러한 현상이 발생합니다. 그래서 예, 들어오는 데이터가 저장됩니다.

+0

정확하게 작동하는 방법과 실행 흐름이 어떤 것인지 분명하지 않습니다. 어떻게하면이 처리되지 않습니다까지 Promise.resolve()'무엇을'worker.then (지난 => processData (데이터도 않습니다)'또한 incomingData (데이터'에서받은 모든 데이터를 저장합니다.하고있다)''합니까? – User7723337

+0

나는 대답에 더 많은 정보를 추가했다. 그러나 정말로 묻는 것은 약속에 대한 기본적인 이해가 필요하다. 나는 당신이 (업데이트의 링크)에 대해 읽어보기를 권유한다. " –

+0

"이제는 이전에이 기능을 실행할 수 없다고 상상해보십시오. 위 코드에서 일어나고있는 것입니다. 들어오는 데이터는 저장됩니다. "-하지만 우리가'worker.then (last = > processData incomingData''의 (데이터)'. 그것은 이전의 뒤에있는 데이터를 하나 개의 기능을 넣습니다. 정확히 – User7723337

0

작업을 수행하는 데 비동기 성이 있다고 가정하면 다음과 같은 약속이있는 재귀 적 비동기식 흐름 제어가 제공 될 수 있습니다. 하나마다 1000MS을 터지는 동안

우리는 arr 배열에 250ms마다 1에-사이 (10)을 임의의 숫자를 unshifting 있습니다. 정의 된 한도는 10 개의 항목이며 한 번 우리가 limit 값에 도달하면 unshifting이 중지됩니다.

function doStgAndPop(a){ 
 
    return new Promise((resolve,reject) => { var id = setTimeout(_ => a.length > 0 ? resolve(a.pop()) : reject(id),1000)}); 
 
} 
 

 
function doStgAndUnshift(a){ 
 
    return new Promise((resolve,reject) => { var id = setTimeout(_ => a.length < limit ? (a.unshift(~~(Math.random()*10+1)),resolve(a)) 
 
                        : reject(id),250)}); 
 
} 
 

 
function runnerPop(a){ 
 
    doStgAndPop(a).then(v => (console.log("pop out resulted:",v),runnerPop(a))) 
 
       .catch(e => (console.log("array is now empty"),clearSetTimeout(e))); 
 
} 
 
function runnerUnshift(a){ 
 
    doStgAndUnshift(a).then(v => (console.log("new array after unshift",JSON.stringify(v)),runnerUnshift(a))) 
 
        .catch(e => (console.log("array limit:",limit,"reached"),clearSetTimeout(e))); 
 
} 
 

 
var limit = 10, 
 
     arr = []; 
 

 
runnerUnshift(arr); 
 
runnerPop(arr);

나는 기본 ES6의 약속을 사용하고 있습니다. doStgAndPop은 약속을 반환하고 1000ms 동안 멈추는 비동기 함수 ( setTimeout)를 실행하고 arr에서 항목을 팝업합니다. doStgAndUnshift은 매우 유사하지만 한계에 도달 할 때까지 250ms마다 항목을 이동하지 않습니다 그것에 도달하면 그것을 거부합니다. runnerPoprunnerUnshift은 각각 doStgAndPopdoStgAndUnshift를 호출하고 약속을받을 수 재귀 함수입니다. then 단계에서 우리는 재귀 적으로 러너 함수를 호출하고 catch 단계에서 작업을 마무리합니다.

+0

Angular Promise에 완전히 익숙하지 않으며 작동 방식에 따라이 코드 흐름을 이해하는 것이 어려울 것입니다. – User7723337

+0

@A_user 방금 내 대답의 맨 끝에 몇 가지 설명을 추가했습니다. 나는 그것이 도움이되기를 바랍니다. – Redu