如何在函数内获取API响应数据?Node.js异步调用问题
别担心,这是JavaScript异步编程里超级常见的入门坑,很多新手都会踩,完全不用不好意思重复问~
问题根源:异步操作的执行顺序
你遇到的核心问题是**client.get是异步操作**——它不会立刻执行完再往下走,而是发起请求后就直接继续执行后面的代码,等API返回数据了才会触发回调函数。
在你的封装函数里:
function geocode(address){ var client = new Client(); var parsed; // 这里发起异步请求,回调函数要等API返回才会跑 client.get(..., function(data, response) { parsed = data.results[0].locations[0].latLng }); // 这里的代码会在回调执行前就运行!所以此时parsed还是undefined return parsed }
当你调用geocode(address)并拿到返回值时,API请求还在网络传输中,回调函数根本没机会修改parsed,自然返回的是初始的undefined。
解决方法:用异步机制处理结果
JavaScript里处理异步结果有几种主流方式,给你列两种最常用的:
1. 传统回调函数
修改geocode函数,让它接收一个回调参数,在异步请求完成后调用这个回调把数据传出去:
var Client = require('node-rest-client').Client; function geocode(address, callback){ var client = new Client(); client.get( `http://www.mapquestapi.com/geocoding/v1/address?key=${mapquestKeys.consumer_key}&location=${address}`, function(data, response) { // 拿到数据后调用回调,第一个参数传错误(如果有的话),第二个传结果 if (response.statusCode !== 200) { return callback(new Error('请求失败')); } var parsed = data.results[0].locations[0].latLng; callback(null, parsed); } ); } // 调用方式 var address = 'New York'; geocode(address, function(err, result) { if (err) { console.error('出错了:', err); return; } console.log('拿到坐标:', result); // 这里就能拿到{lat, lng}了 });
2. 更现代的Promise + async/await
把异步操作包装成Promise,这样代码可读性更好,还能使用async/await语法:
var Client = require('node-rest-client').Client; function geocode(address){ return new Promise((resolve, reject) => { var client = new Client(); client.get( `http://www.mapquestapi.com/geocoding/v1/address?key=${mapquestKeys.consumer_key}&location=${address}`, function(data, response) { if (response.statusCode !== 200) { return reject(new Error('请求失败')); } var parsed = data.results[0].locations[0].latLng; resolve(parsed); } ); }); } // 方式一:用.then()链式调用 var address = 'New York'; geocode(address) .then(result => { console.log('拿到坐标:', result); }) .catch(err => { console.error('出错了:', err); }); // 方式二:用async/await(必须在async函数内使用) async function getLocation() { try { const result = await geocode('New York'); console.log('拿到坐标:', result); } catch (err) { console.error('出错了:', err); } } getLocation();
简单总结一下:JavaScript里的异步操作(比如API请求、定时器)不会"阻塞"代码执行,所以不能像同步函数那样直接return结果,必须用回调、Promise或者async/await这类机制,等异步操作真正完成后再处理数据。
内容的提问来源于stack exchange,提问作者Guy Giesa-Wilson
相关产品推荐
相关产品推荐

