异步函数未返回完成的承诺

时间:2015-09-04 18:50:48

标签: javascript ecmascript-6

我有一个javascript文件,我抓住了用户的地理位置。我把它包裹在一个承诺中,以确保它返回坐标。

geoLocation.js:

const getGeoLocation = () => {
  return new Promise(function(resolve, reject){
    function positionSuccess(position){             
      resolve(position);
    }
    function positionError(error){
      reject('ERROR: ' + error.code + ': ' + error.message);
    };
    navigator.geolocation.getCurrentPosition(positionSuccess, positionError);
  });
};

async function userCoords() {
  const response = await getGeoLocation();
}

module.exports = userCoords;

从这里开始,我将async userCoords函数导入Main.js react组件。在它的渲染方法中,我要求它使用console.log(userCoords()),但我在控制台中获得的是:

enter image description here

看起来它还在等待我的getGeoLocation承诺。我应该做些什么来确保getGeoLocation完全完成并且我可以将它返回到我的Main.js组件的返回坐标?

谢谢!

1 个答案:

答案 0 :(得分:2)

异步函数将始终返回一个promise,即使它已经解决了。您必须使用promise.thenawait。如果你可以使你的渲染函数异步,那么你可以写:

console.log(await userCoords());

异步的函数是有毒的,这意味着调用异步函数(并期望一个已确定的值)的任何函数都必须是异步的。在编程用户界面时,这是特别痛苦的,因为UI代码本质上是同步的。显示来自异步数据源的数据很难做得很好,需要仔细的工程设计。

您可以做的最简单的事情就是独立于渲染周期轮询用户坐标:

var coords_promise = null;
var coords = null;

function render() {
    if (!coords_promise) {
        coords_promise = userCoords().then(function(newCoords) {
            coords = newCoords;
            coords_promise = null;
        });
    }
    console.log(coords);
}

setInterval(render, 20);

这段代码将开始在调用渲染函数时获取坐标。这意味着渲染函数的前几个循环将打印coords变量的初始值,但之后它将使用最新的已确定返回值userCoords()。此代码还确保在未对render()函数进行调用时不进行提取,并且不会对userCoords()进行并行调用。