2017-10-11 53 views
1

,如果你幫我下面的情況下,我會明白:需要幫助有關異步函數執行流程(AWAIT,承諾,node.js中)

鑑於功能:

async function getAllProductsData() { 
    try { 
    allProductsInfo = await getDataFromUri(cpCampaignsLink); 
    allProductsInfo = await getCpCampaignsIdsAndNamesData(allProductsInfo); 
    await Promise.all(allProductsInfo.map(async (item) => { 
     item.images = await getProductsOfCampaign(item.id); 
    })); 
    allProductsInfo = JSON.stringify(allProductsInfo); 
    console.log(allProductsInfo); 
    return allProductsInfo; 
    } catch(err) { 
    handleErr(err); 
    } 
} 

這個功能被觸發時,服務器啓動時,它彙集了來自其他網站的活動信息:獲取數據(getDataFromUri()),然後從數據名稱和ID提取(getCpCampaignsIdsAndNamesData()),然後得到的產品圖片爲每個廣告活動(getProductsOfCampaign());

app.get('/products', async (req, res) => { 
    if (allProductsInfo.length === undefined) { 
    console.log('Pending...'); 
    allProductsInfo = await getAllProductsData(); 
    } 
    res.status(200).send(allProductsInfo); 
}); 

問題描述:

  1. 啓動服務器,等待幾秒鐘,直到getAllProductsData()被執行,做'/產品的

    我還與下面的代碼段express.app GET請求,所有作品都很棒!

  2. 啓動服務器,並立即火'/產品的GET請求」(爲此我說如果與執行console.log(‘等待...’)表達式),我得到損壞結果返回:它包含了所有活動的名稱, ID,但沒有圖像數組。

    • [{ 「ID」: 「1111」, 「名」: 「有些名」},{ 「ID」: 「2222」, 「名」: 「其他一些名字」}], 而我期待
    • [{ 「ID」: 「1111」, 「名」: 「有些名稱」, 「圖片」: 「URI」, 「URI」 ...]} ...]

,我將非常感謝您的幫助有關:

  • 解釋什麼與作爲發生的流執行ync,以及爲什麼不等待圖像數組添加到對象而發送結果?
  • 如果你知道一些有用的文章/規格部分涵蓋了我的話題,我會感激。

謝謝。

回答

2

有使用全局變量allProductsInfo,然後燒製異步使用多個併發的功能,一個巨大的問題。這將創建各種比賽條件,你必須考慮你自己,你有不是圖像數據幸運

您可以輕鬆地通過使allProductsInfo一個局部變量解決這個問題,或者至少不能用它來從getDataFromUrigetCpCampaignsIdsAndNamesData保存中間結果 - 使用不同的(本地!)變量的。

但是,即使你這樣做,你可能射擊getAllProductsData多次,這不應該導致錯誤,但仍然是低效的。這是很容易儲存在全局變量一個承諾,這個初始化一次在信息收集過程的單一調用,只是每次都等待着它 - 當它已經完成,這將是不明顯的。

async function getAllProductsData() { 
    const data = await getDataFromUri(cpCampaignsLink); 
    const allProductsInfo = await getCpCampaignsIdsAndNamesData(allProductsInfo); 
    await Promise.all(allProductsInfo.map(async (item) => { 
    item.images = await getProductsOfCampaign(item.id); 
    })); 
    console.log(allProductsInfo); 
    return JSON.stringify(allProductsInfo); 
} 

const productDataPromise = getAllProductsData(); 
productDataPromise.catch(handleErr); 
app.get('/products', async (req, res) => { 
    res.status(200).send(await productDataPromise); 
}); 

當然,你可能還需要啓動服務器(或/products路由添加到它)數據被加載後,才和簡單服務狀態500,直到然後。此外,您應該考慮在承諾被拒絕後命中路線時發生的情況 - 不確定handleErr的作用。