2016-09-28 83 views
1

我想概括一個使用OpenPGP庫加密表單的腳本。 我與客戶端代碼一些麻煩(JavaScript)的:在while循環中的承諾javascript

var working = formID.elements[0]; 
var counter = 0; 

while (working) { 
    encrypt(working.value).then(function(encrypted_msg) { 
     console.log("processing"); 
     working.value = encrypted_msg; 
    }); 
    console.log("assuming processed"); 
    var counter = counter + 1; 
    var working = formID.elements[counter]; 
} 

下面的代碼應採取每個表單元素和加密它的值。但是,while循環不會等待解析異步encrypt()函數。

我想我需要在這種情況下使用承諾,但我不知道如何和少數教程在while循環中不工作。

幫助?

+0

你使用任何框架angular/react爲前端或純JavaScript? –

+0

@AshashBhandwalkar只有純JavaScript和JQuery。 – Squared

+0

我回答。我希望它能起作用! –

回答

2

大概可以使用jQuery的deferreds的列表中,這樣的事情:

var deferreds = []; 

$.each(formID.elements, function(key, working){ 

    var deferred = $.Deferred(); 
    deferreds.push(deferred); 

    encrypt(working.value).then(function(encrypted_msg) { 
     console.log("processing"); 
     working.value = encrypted_msg; 
     deferred.resolve(); 
    }); 

}); 

$.when.apply($, deferreds).done(function(){ 
    console.log('after all encryptions!'); 
}); 

當然,可以使用原生Promise對象,而不是$.Deferred,但是我覺得$.Deferredmore cross-browser way

UPD2:

基於原生PromisePromise.resolve()(感謝@Bergi)改進的答案。對於encrypt()返回正確承諾的情況,可以跳過方法Promise.resolve()

var promises = []; 

$.each(formID.elements, function(key, working){ 

    var promise = Promise.resolve(encrypt(working.value)) 
     .then(function(encrypted_msg) { 
      console.log("processing"); 
      working.value = encrypted_msg; 
     }); 

    promises.push(promise); 

}); 

Promise.all(promises).then(function(){ 
    console.log('after all encryptions!'); 
}); 
+0

嗯,它的工作。謝謝 ! – Squared

+1

理論上,是的,但[避免延遲反模式](http://stackoverflow.com/q/23803743/1048572)! – Bergi

+0

@Bergi是的,創建過多的延期/促銷是不好的做法。但是我不知道什麼對象返回'encrypt'方法,以及它如何處理'$ .when()'或'Promise.all()'。事實上,這個對象包含'.then'方法,對他來說沒什麼好說的。 我更新了答案,沒有反模式。 – IStranger

1
var iterator = []; 
for (var counter = 0; counter < formID.elements.length; counter++) { 
    var working = formID.elements[counter]; 
    iterator.push(encrypt(working.value)); 
} 

Promise.all(iterator) 
.then(fumction(data){ 
    //Here you have all data 
}) 

您可以像這樣同步您的操作。通過收集所有異步值引用並在他們有數據時指向它們。

如果您的數據是相關的。

function myfunction(previousValue){ 
    if(breaking Condition){ 
     return Promise.resolve(); 
    } 
    return encrypt(working.value).then(function(encrypted_msg) { 
     working.value = encrypted_msg; 
     return myfunction(working); 
    }); 
} 
+0

一個問題,我需要將工作變量傳遞給迭代器。我怎麼能做到這一點? – Squared

+0

請看看。我編輯 –

+0

有一個錯誤,未定義工作變種。仍然試圖讓它工作,壽。 – Squared