2017-09-03 61 views
1

我想用Promise.allmap而不是forEach循環,因此任務可以是異步的。 Promise.all陣列中的所有承諾都會執行並解決。代碼如下所示:。然後Promise.all結果永遠不會執行

loadDistances() { 
    //return new Promise((resolve, reject) => { 
     let rrr; 
     let arr = []; 
     this.geolocation.getCurrentPosition().then((resp) => {    
      // resp.coords.latitude 
      rrr = resp; 
      console.log(rrr + "    rrrrrrrrrrrrrrrrrrrrrrrrrr"); 

      setTimeout(() => { 
      this.distancelist = this.af.list('/profiles/stylists'); 

      let x = 0; 
      this.subscription6 = this.distancelist.subscribe(items => { 

       let mapped = items.map((item) => { 
       return new Promise(resolve => { 
        let rr; 
        //console.log(JSON.stringify(item) + "    *((*&*&*&*&^&*&*&*(&*(&*&*(&(&(&*(    :::" + x); 
        if(item.address == "") { 
        /*if(!item.picURL) { 
         item.picURL = 'assets/blankprof.png'; 
        }*/ 
        //arr.push({'pic':item.picURL, 'salon':item.username, 'distance':"No Address"}); 
        //x++; 
        } 
        else { 
        console.log(item.address + " is the address empty??????"); 
        this.nativeGeocoder.forwardGeocode(item.address) 
         .then((coordinates: NativeGeocoderForwardResult) => { 
         console.log("I AM IN THE GEOCODING ***&&*&*&*&*"); 
          rr = this.round(this.distance(coordinates.latitude, coordinates.longitude, rrr.coords.latitude, rrr.coords.longitude, "M"), 1); 
          if(!item.picURL) { 
          item.picURL = 'assets/blankprof.png'; 
          } 
          arr.push({'pic':item.picURL, 'salon':item.username, 'distance':rr}); 
          console.log("push to the array of results"); 
          //x++; 
          /*console.log(items.length + "   length / x:  " + x); 
          if(items.length - x == 1) { 
          console.log("getting resolved in geocoder ^&^&^&&^^&^&^&"); 
          resolve(arr); 
          }*/ 
          resolve(); 
         }).catch(e => { 
          console.log(e.message + " caught this error"); 
          /*x++; 
          if(items.length - x == 1) { 
          resolve(arr); 
          }*/ 
          resolve(); 
         }) 
        } 

       }) 
       }); 

       let results = Promise.all(mapped); 
       results.then(() => { 
       console.log(JSON.stringify(arr) + " :FOSIEJO:SFJ::EFIJSEFIJS:EFJS:IO THIS IODIOSJ:FDSIJ :DIS"); 
       arr.sort(function(a,b) { 
        return a.distance - b.distance; 
       }); 

       this.distances = arr.slice(); 
       }) 

      });//); 
      }, 1500) 




     /*}).catch((error) => { 
     this.diagnostic.switchToLocationSettings(); 
     console.log('Error getting location', error.message); 
     resolve(); 
     });*/ 

    }); 


    } 

控制檯輸出爲:

[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:27] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:27] console.log: push to the array of results 
[12:38:28] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:28] console.log: push to the array of results 
[12:38:29] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:29] console.log: push to the array of results 
[12:38:29] console.log: I AM IN THE GEOCODING ***&&*&*&*&* 
[12:38:29] console.log: push to the array of results 

交替的消息,使其看起來像它的工作和所有的承諾得到了解決。但是當我做Promise.all這行永遠不會發生在控制檯:

console.log(JSON.stringify(arr) + " :FOSIEJO:SFJ::EFIJSEFIJS:EFJS:IO THIS IODIOSJ:FDSIJ :DIS");

所以它是沒有達到的Promise.allresultsthen

+0

噢,我的,什麼亂七八糟的這段代碼。它做了很多不同的事情。但是,即使開始清理,1500ms的超時時間是多少?總的來說,這是什麼?因爲'this'似乎幾乎涵蓋了從狀態到子模塊到像'round()'這樣的實用函數的所有內容。 – Thomas

+0

當你做到這一點時,將你的代碼切換到異步/等待狀態,它會更清晰地閱讀 - > https://blog.mariusschulz.com/2016/12/09/typescript-2-1-async- await-for-es3-es5 – Lostfields

+0

@Thomas謝謝指出一些事情......因爲我對離子/角/打字稿有點新。因爲如果不是,this.geolocation.getCurrentPosition()。then((resp)=> {')中的代碼在實際獲得位置座標之前運行,我使用'this'來引用到類方法和屬性,以及注入模塊('constructor(xxx:XXXXXX)')。我一直在學習這些東西,並且同時進行得很快,因爲我沒有很多時間來做這件事。 ..我希望更多地關注最佳實踐。 – ewizard

回答

2

你的代碼路徑不解決,特別是:

if(item.address == "") { 
    /*if(!item.picURL) { 
    item.picURL = 'assets/blankprof.png'; 
    }*/ 
    //arr.push({'pic':item.picURL, 'salon':item.username, 'distance':"No Address"}); 
    //x++; 
} 
+0

當然......謝謝! – ewizard

0

這是很容易陷入像@安迪·加斯克爾創建新的承諾時指出死鎖。爲了避免這種情況,你最好做其中的一個;所有這些都可能會引發錯誤不可能或返回1.

function promiseWithTryCatch() { 
    return new Promise((resolve, reject) => { 
    try { 
     let result; 
     // your code 

     resolve(result); 
    } 
    catch(ex) { 
     reject(ex); 
    } 
    }) 
} 

function promiseWithResolve() { 
    return Promise.resolve() 
    .then(() => { 
     let result; 
     // your code 

     return result; 
    }) 
} 

async function promiseWithAsync() { 
    let result; 
    // your code 

    return result; 
} 

替換代碼中的註釋和結束結果放入變量的結果。如果你的代碼中包含的異步代碼,你最好做一個新的功能,以相同的模式,並返回,作爲結果,例如:結果= [承諾方法]

  • 最可怕的一個是「新希望」,如果有的話代碼無法解析或拒絕它將以「死鎖」結束,這就是爲什麼嘗試/捕獲非常重要。
  • 如果您使用的是Promise.resolve(),它會捕獲.then中的任何錯誤,但不要在外面執行任何代碼。否則,您必須捕獲異常並返回Promise.reject(new Error())
  • 最安全的是異步函數,因爲任何「扔」將返回Promise.reject,以及「返回」將返回一個Promise.resolve

玩弄這個例子,但我不得不註釋掉異步/因爲這個片段工具無法處理ES2016。

function nestedPromise(num) { 
 
    return Promise.resolve(' myNestedValue is ' + num); 
 
} 
 

 
function promiseWithTryCatch() { 
 
    return new Promise((resolve, reject) => { 
 
    try { 
 
     let mynumber = 2 + 5; 
 

 
     nestedPromise(mynumber) 
 
     .then((answer) => { 
 
      resolve(answer.trim()); 
 
     }) 
 
     .catch(ex => { 
 
      // error handling for async-code 
 
      reject(ex); 
 
     }) 
 
    } 
 
    catch(ex) { 
 
     // error handling for sync-code 
 
     reject(ex); 
 
    } 
 
    }) 
 
} 
 

 
function promiseWithResolve() { 
 
    return Promise.resolve() 
 
    .then(() => { 
 
     let mynumber = 2 + 5; 
 

 
     return nestedPromise(mynumber); 
 
    }) 
 
    .then((answer) => { 
 
     // do something with the answer 
 
     return answer.trim(); 
 
    }) 
 
} 
 

 
/* 
 
async function promiseWithAsync() { 
 
    let mynumber = 2 + 5; 
 
    let answer = await nestedPromise(mynumber); 
 
    
 
    return answer.trim(); 
 
} 
 
*/ 
 

 
promiseWithTryCatch() 
 
    .then(answer => console.log('promiseWithTryCatch result is ' + answer)) 
 
    .catch(err => console.log('promiseWithAsync error is ' + err.message)); 
 
    
 
promiseWithResolve() 
 
    .then(answer => console.log('promiseWithResolve result is ' + answer)) 
 
    .catch(err => console.log('promiseWithResolve error is ' + err.message)); 
 

 
/* 
 
promiseWithAsync() 
 
    .then(answer => console.log('promiseWithAsync result is' + answer)) 
 
    .catch(err => console.log('promiseWithAsync error is ' + err.message)); 
 
*/

+0

感謝您指出了這一點,您能解釋一下我將如何使用這些方法來避免死鎖? – ewizard

+0

爲每個案例增加了一個示例和更多描述 – Lostfields

相關問題