如何使用异步/等待内部的承诺

发布于 2025-02-13 22:48:40 字数 7252 浏览 1 评论 0原文

我想在此诺言中使用异步/等待,以获取一些API或数据库存储的货币率来转换货币。

就像我想在这里使用这样的等待,但不确定要放置异步。

arrcars["price_client"] = await forexService.convertCurrency(item.regular_price, "EUR", userCurrency);

我发布了整个代码。这里需要一些指导。

这是控制器

    const httpStatus = require('http-status');
    const pick = require('../utils/pick');
    const catchAsync = require('../utils/catchAsync');
    const async = require('async');
    const axios = require('axios');
    const { talixoService } = require('../services');
    const { iwayService } = require('../services');
    const { forexService } = require('../services');
    
        const searchCars = function (req, res) {
            const talixoData = talixoService.findTalixoCars(req.body) //call talixo api in services
            const iwayData = iwayService.findiWayCars(req.body) //call iwaytransfers api in services
        
            if (req.query.usercurrency) {
                var userCurrency = req.query.usercurrency;
            } else {
                var userCurrency = "INR";
            }
        
            return Promise.allSettled([talixoData, iwayData]).then(([restalixo, resiway]) => {
                const taxiresults = [];
                if (restalixo.status === "fulfilled") {
                    //console.log(restalixo.value.data);
                    if (restalixo.value.data.taxis.length) {
                        restalixo.value.data.taxis.forEach(function (item) {
                            arrcars = {};
                            arrcars["carname"] = item.car_model;
                            arrcars["originprice"] = item.regular_price;
                            arrcars["price_client"] = forexService.convertCurrency(item.regular_price, "EUR", userCurrency);
                            arrcars["discountprice_client"] = forexService.convertCurrency(item.discount_price, "EUR", userCurrency);
                            arrcars["packageId"] = item.id;
                            arrcars["image"] = item.image_url;
                            arrcars["freewaittime"] = item.included_waiting_time;
                            arrcars["maxluggage"] = item.luggage;
                            arrcars["maxpassengers"] = item.seats;
                            arrcars["discountprice"] = item.discount_price;
                            arrcars["vehicletype"] = item.vehicle_type;
                            arrcars["vendor"] = "Talixo";
                            arrcars["vehicleremarks"] = "Or Similar";
                            taxiresults.push(arrcars);
                        });
                    }
                    if (restalixo.value.data.limousines.length) {
                        restalixo.value.data.limousines.forEach(function (item) {
                            arrcars = {};
                            arrcars["carname"] = item.car_model;
                            arrcars["originprice"] = item.regular_price;
                            arrcars["price_client"] = forexService.convertCurrency(item.regular_price, "EUR", userCurrency);
                            arrcars["discountprice_client"] = forexService.convertCurrency(item.discount_price, "EUR", userCurrency);
                            arrcars["packageId"] = item.id;
                            arrcars["image"] = item.image_url;
                            arrcars["freewaittime"] = item.included_waiting_time;
                            arrcars["maxluggage"] = item.luggage;
                            arrcars["maxpassengers"] = item.seats;
                            arrcars["discountprice"] = item.discount_price;
                            arrcars["vehicletype"] = item.vehicle_type;
                            arrcars["vendor"] = "Talixo";
                            arrcars["vehicleremarks"] = "Or Similar";
                            taxiresults.push(arrcars);
                        });
                    }
                }
                //iwaytransfers supplier data
                if (resiway.status === "fulfilled") {
                    //console.log(resiway.value.data);
                    if (resiway.value.data.result.length) {
                        resiway.value.data.result.forEach(function (item) {
                            var imgsrc = "https://iwayex.com/images/cars/";
                            arrcars = {};
                            arrcars["carname"] = item.car_class.models[0];
                            arrcars["originprice"] = item.price;
                            arrcars["price_client"] = forexService.convertCurrency(item.price, "EUR", userCurrency);
                            arrcars["discountprice_client"] = forexService.convertCurrency(item.price, "EUR", userCurrency);
                            arrcars["packageId"] = item.price_uid;
                            arrcars["image"] = imgsrc + item.car_class.photo;
                            arrcars["freewaittime"] = item.allowable_time;
                            arrcars["maxluggage"] = "";
                            arrcars["maxpassengers"] = item.car_class.capacity;
                            arrcars["discountprice"] = item.price;
                            arrcars["vehicletype"] = item.vehicle_type;
                            arrcars["vendor"] = "iway Transfers";
                            arrcars["vehicleremarks"] = "Or Similar";
                            taxiresults.push(arrcars);
                        });
                    }
                }
        
                if (taxiresults.length) {
                    sortedresult = taxiresults.sort(function (a, b) {
                        return a.discountprice - b.discountprice;
                    });
                    res.status(200).send(sortedresult)
                }else{
                    res.status(200).send({})
                }
            });
        }

module.exports = {
    searchCars
}

这是我得到的结果样本。

{
carname: "Toyota Prius"
discountprice: 27.5
discountprice_client: {}
freewaittime: 45
image: "https://static.talixo.de/images/vehicles/economy.png"
maxluggage: 3
maxpassengers: 3
originprice: 27.5
packageId: "16021"
price_client: {}
vehicleremarks: "Or Similar"
vehicletype: "limo"
vendor: "Talixo"
}

这里的问题是, 我希望

discountprice_client: Converted Number, 

我能在那里得到空白的对象,如上所述样本中可以看出。 我一直在与异步的另一个函数中使用此功能,然后它可以正常工作。但是在这种情况下,我不确定如何放置异步/等待。

这在内部

forex.service.js内部

    const convertCurrency = async (amount, basecurrency, reqCurrency) => {
        if (basecurrency === reqCurrency) {
            let result = Math.round(amount) + ' ' + reqCurrency;
            return result;
        } else {
            const reqForexData = await getForexbyISO(reqCurrency);
            const baseForexData = await getForexbyISO(basecurrency);
            const amountInUSD = amount / baseForexData.forexRate;
            const amountInreqC = amountInUSD * reqForexData.forexRate;
            let result = Math.round(amountInreqC) + ' ' + reqCurrency;
            return result;
        }
    }

module.exports = {
    convertCurrency
}

I want to use async/await inside this promise.allSettled to convert currency by fetching some api or databased stored currency rates.

like i want to use await here like this, but not sure where to put async.

arrcars["price_client"] = await forexService.convertCurrency(item.regular_price, "EUR", userCurrency);

I have posted my entire code. need some guidance here.

This is controller

    const httpStatus = require('http-status');
    const pick = require('../utils/pick');
    const catchAsync = require('../utils/catchAsync');
    const async = require('async');
    const axios = require('axios');
    const { talixoService } = require('../services');
    const { iwayService } = require('../services');
    const { forexService } = require('../services');
    
        const searchCars = function (req, res) {
            const talixoData = talixoService.findTalixoCars(req.body) //call talixo api in services
            const iwayData = iwayService.findiWayCars(req.body) //call iwaytransfers api in services
        
            if (req.query.usercurrency) {
                var userCurrency = req.query.usercurrency;
            } else {
                var userCurrency = "INR";
            }
        
            return Promise.allSettled([talixoData, iwayData]).then(([restalixo, resiway]) => {
                const taxiresults = [];
                if (restalixo.status === "fulfilled") {
                    //console.log(restalixo.value.data);
                    if (restalixo.value.data.taxis.length) {
                        restalixo.value.data.taxis.forEach(function (item) {
                            arrcars = {};
                            arrcars["carname"] = item.car_model;
                            arrcars["originprice"] = item.regular_price;
                            arrcars["price_client"] = forexService.convertCurrency(item.regular_price, "EUR", userCurrency);
                            arrcars["discountprice_client"] = forexService.convertCurrency(item.discount_price, "EUR", userCurrency);
                            arrcars["packageId"] = item.id;
                            arrcars["image"] = item.image_url;
                            arrcars["freewaittime"] = item.included_waiting_time;
                            arrcars["maxluggage"] = item.luggage;
                            arrcars["maxpassengers"] = item.seats;
                            arrcars["discountprice"] = item.discount_price;
                            arrcars["vehicletype"] = item.vehicle_type;
                            arrcars["vendor"] = "Talixo";
                            arrcars["vehicleremarks"] = "Or Similar";
                            taxiresults.push(arrcars);
                        });
                    }
                    if (restalixo.value.data.limousines.length) {
                        restalixo.value.data.limousines.forEach(function (item) {
                            arrcars = {};
                            arrcars["carname"] = item.car_model;
                            arrcars["originprice"] = item.regular_price;
                            arrcars["price_client"] = forexService.convertCurrency(item.regular_price, "EUR", userCurrency);
                            arrcars["discountprice_client"] = forexService.convertCurrency(item.discount_price, "EUR", userCurrency);
                            arrcars["packageId"] = item.id;
                            arrcars["image"] = item.image_url;
                            arrcars["freewaittime"] = item.included_waiting_time;
                            arrcars["maxluggage"] = item.luggage;
                            arrcars["maxpassengers"] = item.seats;
                            arrcars["discountprice"] = item.discount_price;
                            arrcars["vehicletype"] = item.vehicle_type;
                            arrcars["vendor"] = "Talixo";
                            arrcars["vehicleremarks"] = "Or Similar";
                            taxiresults.push(arrcars);
                        });
                    }
                }
                //iwaytransfers supplier data
                if (resiway.status === "fulfilled") {
                    //console.log(resiway.value.data);
                    if (resiway.value.data.result.length) {
                        resiway.value.data.result.forEach(function (item) {
                            var imgsrc = "https://iwayex.com/images/cars/";
                            arrcars = {};
                            arrcars["carname"] = item.car_class.models[0];
                            arrcars["originprice"] = item.price;
                            arrcars["price_client"] = forexService.convertCurrency(item.price, "EUR", userCurrency);
                            arrcars["discountprice_client"] = forexService.convertCurrency(item.price, "EUR", userCurrency);
                            arrcars["packageId"] = item.price_uid;
                            arrcars["image"] = imgsrc + item.car_class.photo;
                            arrcars["freewaittime"] = item.allowable_time;
                            arrcars["maxluggage"] = "";
                            arrcars["maxpassengers"] = item.car_class.capacity;
                            arrcars["discountprice"] = item.price;
                            arrcars["vehicletype"] = item.vehicle_type;
                            arrcars["vendor"] = "iway Transfers";
                            arrcars["vehicleremarks"] = "Or Similar";
                            taxiresults.push(arrcars);
                        });
                    }
                }
        
                if (taxiresults.length) {
                    sortedresult = taxiresults.sort(function (a, b) {
                        return a.discountprice - b.discountprice;
                    });
                    res.status(200).send(sortedresult)
                }else{
                    res.status(200).send({})
                }
            });
        }

module.exports = {
    searchCars
}

this is the result sample i am getting.

{
carname: "Toyota Prius"
discountprice: 27.5
discountprice_client: {}
freewaittime: 45
image: "https://static.talixo.de/images/vehicles/economy.png"
maxluggage: 3
maxpassengers: 3
originprice: 27.5
packageId: "16021"
price_client: {}
vehicleremarks: "Or Similar"
vehicletype: "limo"
vendor: "Talixo"
}

here the problem is,
i expect

discountprice_client: Converted Number, 

but i am getting blank object there as can be seen in above result sample.
i have been using this in another function with async await, then it works fine. but in this case, i am not sure how to put async/await.

this is inside

forex.service.js

    const convertCurrency = async (amount, basecurrency, reqCurrency) => {
        if (basecurrency === reqCurrency) {
            let result = Math.round(amount) + ' ' + reqCurrency;
            return result;
        } else {
            const reqForexData = await getForexbyISO(reqCurrency);
            const baseForexData = await getForexbyISO(basecurrency);
            const amountInUSD = amount / baseForexData.forexRate;
            const amountInreqC = amountInUSD * reqForexData.forexRate;
            let result = Math.round(amountInreqC) + ' ' + reqCurrency;
            return result;
        }
    }

module.exports = {
    convertCurrency
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝天白云 2025-02-20 22:48:40

您可以做:

// notice the `async` before `function`
resiway.value.data.result.forEach(async function (item) {
  // ...
  arrcars = {};
  arrcars["price_client"] = await forexService.convertCurrency(item.price, "EUR", userCurrency);
  arrcars["discountprice_client"] = await forexService.convertCurrency(item.price, "EUR", userCurrency);
  // ...
});

但是它可能导致意外的行为,

我会这样做

// add missing `async`
return Promise.allSettled([talixoData, iwayData]).then(async ([restalixo, resiway]) => {
  // ...
  // await for all loop at once to avoid odd side effects
  await Promise.all(resiway.value.data.result.map(async function (item) {
    // ...
    arrcars = {};
    arrcars["price_client"] = await 
  forexService.convertCurrency(item.price, "EUR", userCurrency);
    arrcars["discountprice_client"] = await 
  forexService.convertCurrency(item.price, "EUR", userCurrency);
    // ...
  }));
  // ...
});

You could do:

// notice the `async` before `function`
resiway.value.data.result.forEach(async function (item) {
  // ...
  arrcars = {};
  arrcars["price_client"] = await forexService.convertCurrency(item.price, "EUR", userCurrency);
  arrcars["discountprice_client"] = await forexService.convertCurrency(item.price, "EUR", userCurrency);
  // ...
});

But it can lead to unexpected behaviours

I would do this

// add missing `async`
return Promise.allSettled([talixoData, iwayData]).then(async ([restalixo, resiway]) => {
  // ...
  // await for all loop at once to avoid odd side effects
  await Promise.all(resiway.value.data.result.map(async function (item) {
    // ...
    arrcars = {};
    arrcars["price_client"] = await 
  forexService.convertCurrency(item.price, "EUR", userCurrency);
    arrcars["discountprice_client"] = await 
  forexService.convertCurrency(item.price, "EUR", userCurrency);
    // ...
  }));
  // ...
});
兲鉂ぱ嘚淚 2025-02-20 22:48:40

简化您的服务

您正在编写Talixo和Iway服务,但是使用结果很困难。而不是返回整个响应,而是将重要的字段返回给您的消费者 -

// services/talixo_service.js

async function findTalixoCars(query) {
  const result = await // ... perform request
  return result.value.data ?? [] // <- return relevant data
}

请注意,我们使用返回_____ ?? []为确保数组始终返回 -

// services/iway_service.js

async function findiWayCars(query) {
  const result = await // ... perform request
  return result.value.data.result ?? [] // <- return relevant data
}

searchCars

使用简化的服务,我们编写了searchcars的高级实现。而不是使用Promise.allsettled我们可以使用.catch(_ =&gt; [])潜在的失败以保证我们具有数组结果。这减少了对逻辑检查和代码分支的需求,以使代码更具声明性,并且不容易出现错误 -

async function searchCars(req, res) {
  const [talixo, iway] = await Promise.all([
    talixoService.findTalixoCars(req.body).catch(_ => []),
    iwayService.findiWayCars(req.body).catch(_ => [])
  ])

  const userCurrency = req.query.usercurrency ?? "INR"

  const taxis = [
    ...await Promise.all(talixo.taxis.map(item => fromTalixo(item, userCurrency))),
    ...await Promise.all(talixo.limousines.map(item => fromTalixo(item, userCurrency))),
    ...await Promise.all(iway.map(item => fromIway(item, userCurrency)))
  ]
  
  res.status(200).send(
    taxis.sort((a,b) => a.discountprice - b.discountprice)
  )
}

数据映射

上面的搜索功能取决于fromtalixo。这些映射功能降低了代码的复杂性和重新定位,并为我们提供了一个良好的概念模型,以从远程服务映射到我们本地数据 -

async function fromTalixo(data, userCurrency) {
  return {
    carname: data.car_model,
    originprice: data.regular_price,
    price_client: await forexService.convertCurrency(data.regular_price, "EUR", userCurrency),
    discountprice_client: await forexService.convertCurrency(data.discount_price, "EUR", userCurrency),
    packageId: data.id,
    image: data.image_url,
    freewaittime: data.included_waiting_time,
    maxluggage: data.luggage,
    maxpassengers: data.seats,
    discountprice: data.discount_price,
    vehicletype: data.vehicle_type,
    vendor: "Talixo",
    vehicleremarks: "Or Similar",
  }
}
async function fromIway(data, userCurrency) {
  return {
    carname: data.car_class.models[0],
    originprice: data.price,
    price_client: await forexService.convertCurrency(data.price, "EUR", userCurrency),
    discountprice_client: await forexService.convertCurrency(data.price, "EUR", userCurrency),
    packageId: data.price_uid,
    image: `https://iwayex.com/images/cars/${data.car_class.photo}`,
    freewaittime: data.allowable_time,
    maxluggage: "",
    maxpassengers: data.car_class.capacity,
    discountprice: data.price,
    vehicletype: data.vehicle_type,
    vendor: "iway Transfers",
    vehicleremarks: "Or Similar",
  }
}

simplify your services

You are writing the Talixo and Iway services but using the result is difficult. Instead of returning the entire response, return the fields that matter to your consumer -

// services/talixo_service.js

async function findTalixoCars(query) {
  const result = await // ... perform request
  return result.value.data ?? [] // <- return relevant data
}

Notice we use return _____ ?? [] to ensure that an array is always returned -

// services/iway_service.js

async function findiWayCars(query) {
  const result = await // ... perform request
  return result.value.data.result ?? [] // <- return relevant data
}

searchCars

With simplified services, we write a high-level implementation of searchCars. Instead of using Promise.allSettled we can use .catch(_ => []) on potential failures to guarantee we have an array result. This reduces the need for logical checks and code branches to make the code more declarative and less prone to errors -

async function searchCars(req, res) {
  const [talixo, iway] = await Promise.all([
    talixoService.findTalixoCars(req.body).catch(_ => []),
    iwayService.findiWayCars(req.body).catch(_ => [])
  ])

  const userCurrency = req.query.usercurrency ?? "INR"

  const taxis = [
    ...await Promise.all(talixo.taxis.map(item => fromTalixo(item, userCurrency))),
    ...await Promise.all(talixo.limousines.map(item => fromTalixo(item, userCurrency))),
    ...await Promise.all(iway.map(item => fromIway(item, userCurrency)))
  ]
  
  res.status(200).send(
    taxis.sort((a,b) => a.discountprice - b.discountprice)
  )
}

data mapping

The search function above depends on fromTalixo and fromIway. These mapping functions reduce code complexity and repitition and gives us a good conceptual model for how data gets mapped from the remote services to our local data -

async function fromTalixo(data, userCurrency) {
  return {
    carname: data.car_model,
    originprice: data.regular_price,
    price_client: await forexService.convertCurrency(data.regular_price, "EUR", userCurrency),
    discountprice_client: await forexService.convertCurrency(data.discount_price, "EUR", userCurrency),
    packageId: data.id,
    image: data.image_url,
    freewaittime: data.included_waiting_time,
    maxluggage: data.luggage,
    maxpassengers: data.seats,
    discountprice: data.discount_price,
    vehicletype: data.vehicle_type,
    vendor: "Talixo",
    vehicleremarks: "Or Similar",
  }
}
async function fromIway(data, userCurrency) {
  return {
    carname: data.car_class.models[0],
    originprice: data.price,
    price_client: await forexService.convertCurrency(data.price, "EUR", userCurrency),
    discountprice_client: await forexService.convertCurrency(data.price, "EUR", userCurrency),
    packageId: data.price_uid,
    image: `https://iwayex.com/images/cars/${data.car_class.photo}`,
    freewaittime: data.allowable_time,
    maxluggage: "",
    maxpassengers: data.car_class.capacity,
    discountprice: data.price,
    vehicletype: data.vehicle_type,
    vendor: "iway Transfers",
    vehicleremarks: "Or Similar",
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文