2017-09-03 32 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

相关问题