在另一个文件中调用异步函数并在其中使用.then

时间:2020-08-29 09:37:00

标签: javascript reactjs asynchronous redux

我试图从我的getFunc.js文件中调用async函数getFunc()我的bodyOfApp.component.js并使用.then来使用它的返回值

getFunc.js

import React from "react";

import { connect } from "react-redux";

import timeDiff from "./timeDiff";

import { currentProjectData } from "./redux/projectData/projectData.actions";

const getFunc = async () => {

    let dataOfTripCard = {};

    const create_UUID = () => {
        var dt = new Date().getTime();
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = (dt + Math.random() * 16) % 16 | 0;
            dt = Math.floor(dt / 16);
            return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        });
        return uuid;
    }

    const username = //my username (string value);
    const weatherbitAPIKey = //my weatherbit APIKey (string value);
    const pixabayAPIKey = //my pixabay APIKey username (string value);

    const baseURLGeo = "http://api.geonames.org/searchJSON?q=";
    const baseURLWeatherCurrent = "https://api.weatherbit.io/v2.0/current?";
    const baseURLWeatherForecast = "https://api.weatherbit.io/v2.0/forecast/daily?";
    const baseURLPixabay = "https://pixabay.com/api/?";

    const city = this.props.currentInputs.city;
    const depDateFromUser = this.props.currentInputs.depDateFromUser;
    const returnDateFromUser = this.props.currentInputs.returnDateFromUser;

    // Create a new date instance dynamically with JS
    const d = new Date();
    const newDate = d.getMonth() + 1 + '/' + d.getDate() + '/' + d.getFullYear();

    const resGeo = await fetch(baseURLGeo + encodeURI(city) + "&username=" + username);

    try {
        const data = await resGeo.json();
        const countryName = data.geonames[0].countryName;
        const latitude = data.geonames[0].lat;
        const longitude = data.geonames[0].lng;
        const daysLeft = timeDiff(newDate, depDateFromUser, returnDateFromUser);

        const resWeather = await fetch(
            ((daysLeft > 7) ? baseURLWeatherForecast : baseURLWeatherCurrent) + "key=" + weatherbitAPIKey + "&lat=" + latitude + "&lon=" + longitude
        );

        const data2 = await resWeather.json();
        const weather = data2.data[0].weather.description;

        const resPixabayPhoto = await fetch(baseURLPixabay + "key=" + pixabayAPIKey + "&q=" + encodeURI(city) + "+tourism&image_type=photo");

        const data3 = await resPixabayPhoto.json();
        const cityPhoto = data3.hits[0].webformatURL;

        // id generated by create_UUID function
        const currentId = create_UUID();

        const tripData = {
            cityPhoto: cityPhoto,
            country: countryName,
            date: newDate,
            depDate: depDateFromUser,
            retDate: returnDateFromUser,
            daysLeft: daysLeft,
            weather: weather,
            temp: (daysLeft > 7) ? {
                low_temp: data2.data[0].low_temp,
                max_temp: data2.data[0].max_temp,
                trueOrFalse: true //For the if statement in updateUI in the client side
            } : {
                    temp: data2.data[0].temp,
                    trueOrFalse: false //For the if statement in updateUI in the client side
                },
            lat: latitude,
            lng: longitude,
            tripId: currentId
        };

        dataOfTripCard[currentId] = tripData;

        return dataOfTripCard;

    } catch (error) {
        console.log("error", error);
        //appropriately handle the error
    }

};

const mapStateToProps = state => ({
    currentInputs: state.inputs.currentInputs
});

const mapDispatchToProps = dispatch => ({
    currentProjectData: projectData => dispatch(currentProjectData(projectData))
})

export default connect(mapStateToProps, mapDispatchToProps)(getFunc);

bodyOfApp.component.js

import React from "react";

import { connect } from "react-redux";

import { currentInputs } from "../../redux/inputs/inputs.actions";
import { toggleSubmittedOrNot } from "../../redux/pop-up/pop-up.actions";
import { toggleShowPopUp } from "../../redux/pop-up/pop-up.actions";
import { currentProjectData } from "../../redux/projectData/projectData.actions";

import MyTripsHolder from "../myTripsHolder/myTripsHolder.component";

import getFunc from "../../getFunc";

import './bodyOfApp.styles.scss'    

class BodyOfApp extends React.Component {

performAction = (e) => {
    e.preventDefault();


//some code here

getFunc().then((dataOfTripCard) => {
  this.props.currentProjectData({
     dataOfTripCard
  })
});
}
 
render() {
     return (
       //jsx code here
     )
  }
}

   

//and at the bottom of the file:
const mapDispatchToProps = dispatch => ({
  currentInputs: inputs => dispatch(currentInputs(inputs)),
  toggleSubmittedOrNot: popUp => dispatch(toggleSubmittedOrNot(popUp)),
  toggleShowPopUp: () => dispatch(toggleShowPopUp()),
  currentProjectData: projectData => dispatch(currentProjectData(projectData))
    })


export default connect(null, mapDispatchToProps)(BodyOfApp);

但是我收到此错误: TypeError:Object(...)不是函数

Here's the TypeError screenshot

是我在另一个文件(bodyOfApp.component.js)中调用getFunc()异步函数的方式,对吗?如果是的话,我应该怎么称呼它?

3 个答案:

答案 0 :(得分:0)

您收到此错误,因为getFunc().then((dataOfTripCard) => {...}箭头功能阻止了thisthis.props.currentProjectData({dataOfTripCard})的范围

解决此问题的一种方法是从不阻塞this范围的常规函数​​中调用getFunc()。

async function getreturnedFunc() {
   try {
           const dataOfTripCard = await getFunc();
           this.props.currentProjectData({dataOfTripCard});
   }catch (e) {
           console.log(e);   
   } 
}

getreturnedFunc();

答案 1 :(得分:0)

导出connect时,您需要删除getFunc

export default getFunc;

connect仅在导出React组件时使用。

答案 2 :(得分:0)

redux的 class ManuallyAddressFragment : Fragment() { lateinit var viewmodel: ViewModelRoom override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val layoutview = inflater.inflate(R.layout.manually_address_fragment, container, false) val database = DataBaseRoom(layoutview.context) val repos = RepositoryCart(database) val factory = FactoryRoom(repos) viewmodel = ViewModelProvider(ViewModelStoreOwner { viewModelStore }, factory).get(ViewModelRoom::class.java) val btncancle: Button = layoutview.btn_cancle val btnsubmit: Button = layoutview.btn_submit_address btnsubmit.setOnClickListener { val edittext = layoutview.edit_address_manually if (edittext.text.toString().isEmpty()) { Toast.makeText(context, R.string.submit_btn, Toast.LENGTH_SHORT).show() } else { val insert = (AddressTb( null , edittext.text.toString())) viewmodel.insertaddress(insert) childFragmentManager.beginTransaction() .setCustomAnimations( R.anim.anim_fragment_manually, R.anim.anim_fragment_chooseaddress ) .replace(R.id.manually_container, ChosseAddress()) .commit() Toast.makeText(context, "آدرس شما با موفقیت ثبت شد", Toast.LENGTH_SHORT).show() } } btncancle.setOnClickListener { childFragmentManager.beginTransaction() .setCustomAnimations( R.anim.anim_fragment_manually, R.anim.anim_fragment_chooseaddress ) .replace(R.id.manually_container, ChosseAddress()) .commit() } return layoutview } }``` 函数将返回您未预期的其他内容。我建议不要使用任何Redux连接,但允许connect函数接受将通过getFunc组件传递的参数。

在箭头函数中也使用BodyOfApp将保留函数的范围,而不引用this函数。

getFunc

使用从Redux连接的const getFunc = async (currentInputs) => { let dataOfTripCard = {}; const create_UUID = () => { var dt = new Date().getTime(); var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = (dt + Math.random() * 16) % 16 | 0; dt = Math.floor(dt / 16); return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16); }); return uuid; } const username = //my username (string value); const weatherbitAPIKey = //my weatherbit APIKey (string value); const pixabayAPIKey = //my pixabay APIKey username (string value); const baseURLGeo = "http://api.geonames.org/searchJSON?q="; const baseURLWeatherCurrent = "https://api.weatherbit.io/v2.0/current?"; const baseURLWeatherForecast = "https://api.weatherbit.io/v2.0/forecast/daily?"; const baseURLPixabay = "https://pixabay.com/api/?"; const city = currentInputs.city; const depDateFromUser = currentInputs.depDateFromUser; const returnDateFromUser = currentInputs.returnDateFromUser; // Create a new date instance dynamically with JS const d = new Date(); const newDate = d.getMonth() + 1 + '/' + d.getDate() + '/' + d.getFullYear(); const resGeo = await fetch(baseURLGeo + encodeURI(city) + "&username=" + username); try { const data = await resGeo.json(); const countryName = data.geonames[0].countryName; const latitude = data.geonames[0].lat; const longitude = data.geonames[0].lng; const daysLeft = timeDiff(newDate, depDateFromUser, returnDateFromUser); const resWeather = await fetch( ((daysLeft > 7) ? baseURLWeatherForecast : baseURLWeatherCurrent) + "key=" + weatherbitAPIKey + "&lat=" + latitude + "&lon=" + longitude ); const data2 = await resWeather.json(); const weather = data2.data[0].weather.description; const resPixabayPhoto = await fetch(baseURLPixabay + "key=" + pixabayAPIKey + "&q=" + encodeURI(city) + "+tourism&image_type=photo"); const data3 = await resPixabayPhoto.json(); const cityPhoto = data3.hits[0].webformatURL; // id generated by create_UUID function const currentId = create_UUID(); const tripData = { cityPhoto: cityPhoto, country: countryName, date: newDate, depDate: depDateFromUser, retDate: returnDateFromUser, daysLeft: daysLeft, weather: weather, temp: (daysLeft > 7) ? { low_temp: data2.data[0].low_temp, max_temp: data2.data[0].max_temp, trueOrFalse: true //For the if statement in updateUI in the client side } : { temp: data2.data[0].temp, trueOrFalse: false //For the if statement in updateUI in the client side }, lat: latitude, lng: longitude, tripId: currentId }; dataOfTripCard[currentId] = tripData; return dataOfTripCard; } catch (error) { console.log("error", error); //appropriately handle the error } }; 应用的道具,并将其传递给BodyOfApp函数。

getFunc