在异步功能中推送到数组不起作用

时间:2019-01-08 22:50:57

标签: javascript node.js asynchronous async-await

这是我的代码:

exports.propertyById = async (req, res) => {
    try {
        const {propertyId} = _.get(req, 'params'),
        propertyData = await bService.getPropertyById(propertyId);
        console.log(propertyData);
        const propertyPhotoList = [];
        async function getPhotoData(item, index){
            const id = item.split('#')[1];
            const response = await fetch(`http://localhost:4000/api/propertyphoto/${id}`);
            const body = await response.json();
            console.log(body);
            propertyPhotoList.push(body);
        }
        propertyData.PropertyPhotos.map(getPhotoData);
        console.log(propertyPhotoList);
        return res.success(res, propertyData);
    } catch (err) {
        return res.error(res, err.response.status || 500, err.response.statusText || err);
    }
}

让我感到困惑的是,异步函数'getPhotoData'中的'console.log(body)'返回了JSON对象。

但是异步函数'getPhotoData'之外的数组仍返回为空的[[]'。

我不确定对象是否被成功推送,或者这是否与异步/等待有关。我来自回调,所以这对我来说仍然是新的。

我正在Ubuntu 18.10上使用Node.js v8.12.0。

3 个答案:

答案 0 :(得分:1)

您需要使用Promise.allawait

await Promise.all(propertyData.PropertyPhotos.map(getPhotoData));

以下是带有修复程序的完整代码:

exports.propertyById = async (req, res) => {
    try {
        const {propertyId} = _.get(req, 'params'),
        propertyData = await bService.getPropertyById(propertyId);
        console.log(propertyData);
        const propertyPhotoList = [];
        async function getPhotoData(item, index){
            const id = item.split('#')[1];
            const response = await fetch(`http://localhost:4000/api/propertyphoto/${id}`);
            const body = await response.json();
            console.log(body);
            propertyPhotoList.push(body);
        }
        await Promise.all(propertyData.PropertyPhotos.map(getPhotoData));
        console.log(propertyPhotoList);
        return res.success(res, propertyData);
    } catch (err) {
        return res.error(res, err.response.status || 500, err.response.statusText || err);
    }
}

您的代码无法正常工作的原因是,您没有在发送响应之前等待对getPhotoData的所有调用完成。

答案 1 :(得分:1)

两个问题:

  1. 您不应使用.map产生副作用。它返回一个新数组,因此您应该使用它。

  2. .mapasync函数一无所知。您要做的就是创建一系列承诺。当.map并且函数返回时,promise还没有“完成”。您需要await全部。

话虽如此:

async function getPhotoData(item, index){
    const id = item.split('#')[1];
    const response = await fetch(`http://localhost:4000/api/propertyphoto/${id}`);
    return await response.json();
}
const propertyPhotoList = await Promise.all(
    propertyData.PropertyPhotos.map(getPhotoData)
);

答案 2 :(得分:1)

由于回调是异步的,因此您需要等待所有映射函数完成后才能打印新的propertyPhotoList-这可以通过Promise.all完成。如果您只是return在新数组中想要的项目,则无需分配给外部数组:

const propertyPhotoList = await Promise.all(
  propertyData.PropertyPhotos.map(getPhotoData)
);

async function getPhotoData(item, index){
  const id = item.split('#')[1];
  const response = await fetch(`http://localhost:4000/api/propertyphoto/${id}`);
  const body = await response.json();
  return body;
}