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

9 javascript asynchronous node.js 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

让我感到困惑的是,异步函数“getPhotoData”内的“console.log(body)”完美地返回了 JSON 对象。

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

我不确定该对象是否未成功推送,或者这是否是异步/等待的某种问题。我来自回调,所以这对我来说仍然是新的。

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

Fel*_*ing 8

两个问题:

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

  2. .mapasync对函数一无所知。您所做的就是创建一系列承诺。当.map你的函数返回时,承诺还没有“完成”。你需要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)
);
Run Code Online (Sandbox Code Playgroud)


Sim*_*leJ 5

您需要使用Promise.allawait

await Promise.all(propertyData.PropertyPhotos.map(getPhotoData));
Run Code Online (Sandbox Code Playgroud)

这是修复后的完整代码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

您的代码不起作用的原因是您getPhotoData在发送响应之前没有等待所有调用完成。