承诺返回undefined

时间:2017-09-17 15:08:39

标签: javascript promise

export function getHotOffers() {
    let offers;
    getRequest('/hot-offers').then(x => offers = x);
    alert(offers);
    return JSON.parse(offers);
}

这是我输出的功能。它以异步方式向服务器发出请求并获取JSON字符串。当我调试项目时,一切正常,警报返回字符串但是当我执行代码时,警报返回undefined。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

这不是承诺的工作方式。 getRequest()之后的代码并没有等待承诺完成 - 它只是立即运行。

export function getHotOffers() {
    let offers;
    getRequest('/hot-offers').then( x =>
       //this only happens after the request is done
       offers = x 
    );
    //this code runs right away, before the request completes
    alert(offers);
    //so does this, so "offers" will be undefined at this point
    return JSON.parse(offers);
}

请求返回后运行的所有代码都应该在你的回调中,如下所示:

export function getHotOffers() {
    return getRequest('/hot-offers');
}

//somewhere else
getHotOffers().then( offers => {
   useTheOffers( offers );
});

答案 1 :(得分:1)

数据不是同步可用的。您需要使用承诺才能访问优惠。

>>> b=[1, 2, 1, 1, 3, 2, 1]
>>> [sum(f(b,5,int(listt[u]),int(listt[u+1]))) for u in range(0,len(listt)-1)]
[4, 1, 5]
>>>

同样,任何调用此函数的代码都将获得一个承诺,并且必须使用其public class FragmentHome extends Fragment { private SearchView search; View view; DatabaseReference dataRef; private FirebaseListAdapter<String> firebaseListAdapter; ListView mListView; private TextView text; ArrayList<String> city=new ArrayList<String>(); private int i=0; private String data,val,var; ArrayAdapter<String> adapter; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable final Bundle savedInstanceState) { View v= inflater.inflate(R.layout.activity_fragment_home,container,false); if (container!=null){ container.removeAllViews(); } search= (SearchView) v.findViewById(R.id.search); search.onActionViewExpanded(); search.setIconified(false); search.setQueryHint("Search Docter By City Or Department"); mListView= (ListView) v.findViewById(R.id.mList); mListView.setVisibility(View.INVISIBLE); dataRef=FirebaseDatabase.getInstance().getReference().child("Docters"); adapter=new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, city); mListView.setAdapter(adapter); dataRef.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { data=dataSnapshot.child("city").getValue(String.class); val=dataSnapshot.child("department").getValue(String.class); if (!city.contains(data)){ city.add(data); } if (!city.contains(val)){ city.add(val); } adapter.notifyDataSetChanged(); } @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) { data=dataSnapshot.child("city").getValue(String.class); val=dataSnapshot.child("department").getValue(String.class); city.add(data); city.add(val); city.add(var); adapter.notifyDataSetChanged(); } @Override public void onChildRemoved(DataSnapshot dataSnapshot) { } @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) { } @Override public void onCancelled(DatabaseError databaseError) { } }); search.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String text) { return false; } @Override public boolean onQueryTextChange(String text) { if (!text.isEmpty()){ mListView.setVisibility(View.VISIBLE); adapter.getFilter().filter(text); }else{ mListView.setVisibility(View.INVISIBLE); } return false; } }); mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String itemRef = (String) adapter.getItem(position); search.setVisibility(View.INVISIBLE); mListView.setVisibility(View.INVISIBLE); FragmentTransaction ft=getChildFragmentManager().beginTransaction(); DocterList fragment=new DocterList(); Bundle item=new Bundle(); item.putString("item",itemRef); fragment.setArguments(item); ft.replace(R.id.activity_fragment_home,fragment); ft.addToBackStack(null); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); ft.commit(); } }); return v; }} 方法来获取最终值。

export function getHotOffers() {
    let offerPromise = getRequest('/hot-offers')
        .then(offers => JSON.parse(offers));
    return offerPromise;
}

答案 2 :(得分:1)

您的代码在调用传递给then的回调之前继续。

使用async/await,您可以绕过这一点,并提高代码的易读性:

&#13;
&#13;
// emulate your "getRequest" function which returns a promise:
async function getRequest(path) {
    await new Promise(resolve => setTimeout(resolve, 500)); // simulate response delay
    const offers = ['hot-offer-1', 'hot-offer-2', 'hot-offer-3'];
    return offers;
}

async function getHotOffers() {
    const offers = await getRequest('/hot-offers');
    console.log(offers);
    return JSON.parse(offers);
}

getHotOffers();
&#13;
&#13;
&#13;