2016-08-31 4 views
0

Я разрабатываю приложение Javascript. Это моя первая попытка в несколько более сложном приложении, и я сталкиваюсь с проблемами с обещаниями.Javascript Обещает не помогать

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Images</title> 
    <meta name="viewport" content="initial-scale=1.0"> 
    <meta charset="utf-8"> 
    <style> 
     ... 
    </style> 
    <script src="http://js.pusher.com/2.2/pusher.min.js"></script> 
    <script async defer 
     src="https://maps.googleapis.com/maps/api/js?key=key&callback=initMap"> 
    </script> 
    </head> 
    <body> 
    <div id="map"></div> 

    <script> 
     var map; 

     //setup Pusher API 
     var channel = "channel"; 
     var pusher = new Pusher(appid); 
     var title; 
     var Channel = pusher.subscribe(channel); 

     function getTitle() { 
     return new Promise(function(resolve, reject) { 
      Channel.bind("new-listing", function(listing) { 
       title = listing['title'];  
       resolve(title); 
      }, 0); 
      }); 
     } 

     getTitle().then(function(title) { 
     return title; 
     }); 
     // console.log("Title: " + title); 

     function findCoordinates() { 
      return new Promise(function(resolve, reject) { 
      geocoder.geocode({ 'address': address}, function(results, status) { 
       latitude = results[0].geometry.location.lat(); 
       longitude = results[0].geometry.location.lng(); 

      resolve(latitude, longitude); 
      }, 0); 
      }); 

     } 

     findCoordinates().then(function(latitude, longitude) { 
     console.log("Latitude: " + latitude); 
     console.log("Longitude: " + longitude); 
     }); 
     // console.log("Latitude: " + latitude); 

     function initMap() { 
     var postion = {lat: latitude, lng: longitude}; //here I need latitude and longitude 
     var map = new google.maps.Map(document.getElementById('map'), { 
      zoom: 3, 
      center: postion 
     }); 

     var marker = new google.maps.Marker({ 
      position: postion, 
      map: map, 
      title: title //here I need title 
     }); 

     marker.addListener('click', function() { 
      infowindow.open(map, marker); 
     }); 

     } 
    </script> 

    </body> 

</html> 

У меня есть три вопроса:

  1. Хотя обещания работают, проблема в том, что название до сих пор не доступны за пределами этого обещания
  2. То же самое с широтой + мне нужно иметь и широту и долгота
  3. Другая проблема заключается в том, что мой код теперь жалуется, что геокодер не определен внутри обещания.

Любая обратная связь действительно ценится.

+0

Объем 'title' является ожидаемый один (как против «широты» и «долготы»), но ваша фактическая проблема - это асинхронность обратных вызовов. – Bergi

+0

Я прочитал ответ на аналогичный вопрос и, при необходимости, уточнил свой вопрос. Должен признать, что даже после прочтения ответа я этого не вижу. – wiwa1978

+0

'setTimeout' похоже на' Channel.bind', а '' Test message'' похоже на 'listing ['title']'. С обещанием для этого и обещанием для координат вы можете использовать 'Promise.all', а затем вызвать свой' initMap', как только все данные придут. – Bergi

ответ

0

Проблема заключается в том, что название до сих пор не доступны за пределами этого обещания

Он никогда не будет. Это может позволить вам получить к нему доступ до того, как оно будет инициализировано, поэтому у вас не будет глобальной переменной для названия - у вас есть глобальное обещание.
Вы можете получить доступ к названию, позвонив по номеру then по обещанию, которое, возможно, понадобится, чтобы дождаться, когда значение поступит.

То же самое с широтой + мне нужно иметь как широта и долгота доступные

Same здесь. Обратите внимание, что вы не можете позвонить resolve с двумя аргументами, вам нужно передать объект вместо этого.

Еще одна проблема заключается в том, что мой код теперь жалуется, что геокодер не определен внутри обещания.

Вряд ли это изменилось. Возможно, вам нужно подождать с вызовом findCoordinates, пока не загрузится скрипт геокодирования.

Большинство кода выглядит хорошо уже, теперь вы просто должны хранить обещания в переменных, и ждать их в initMap функции:

function getTitle(channel) { 
    return new Promise(function(resolve, reject) { 
    channel.bind("new-listing", resolve); 
    }).then(function(listing) { 
    return listing['title']; 
    }); 
} 

function findCoordinates(address) { 
    return new Promise(function(resolve, reject) { 
    geocoder.geocode({ 'address': address}, function(results, status) { 
     // if (status not ok) return reject(status); 
     resolve(results); 
    }, 0); 
    }).then(function(results) { 
    var latitude = results[0].geometry.location.lat(); 
    var longitude = results[0].geometry.location.lng(); 
    console.log("Latitude: " + latitude); 
    console.log("Longitude: " + longitude); 
    return {lat: latitude, lng: longitude}); 
    }); 
} 

//setup Pusher API 
var pusher = new Pusher(appid); 
var channel = pusher.subscribe("channel"); 

var titlePromise = getTitle(channel); 
var coordinatesPromise = findCoordinates(…); // dunno where you got the address from 

// called by the google maps script when ready 
function initMap() { 
    Promise.all([titlePromise, coordinatesPromise]).then(function(res) { 
    var title = res[0]; 
    var position = res[1]; 

    var map = new google.maps.Map(document.getElementById('map'), { 
     zoom: 3, 
     center: position 
    }); 
    var marker = new google.maps.Marker({ 
     position: position, 
     map: map, 
     title: title 
    }); 

    marker.addListener('click', function() { 
     infowindow.open(map, marker); 
    }); 
    }); 
} 
+0

Любопытно услышать причину падения. – Bergi

+0

Не исходит от меня, я просто поддержал. Попробуй свои предложения и отчитайся. – wiwa1978