简体   繁体   English

在 JavaScript 开关/案例中做出承诺

[英]Making a promise work inside a JavaScript switch/case

I having a problem (well two if I'm honest) getting a promise or a callback to work inside a switch-case.我有一个问题(老实说是两个问题)在 switch-case 中得到一个承诺或回调。 Here is the basic code.这是基本代码。

switch (page) {

  case 'contact':

   alert('contact in switch');

   var promise = $.get(page +'.json');
   promise.then(function(data){
     console.log("Items back! ", data);                     
   });

  break;
  .......

  console.log("Response data: ", data); // This is undefined

I understand that due to the nature of async functions, the switch is falling through to the break before the data comes back, making data log as undefined .我知道由于异步函数的性质,在数据返回之前,开关正在break ,使data记录为undefined So I thought putting the break inside the callback would work but it doesn't.所以我认为将break放在回调中会起作用,但事实并非如此。 When I do that the app stops working entirely.当我这样做时,应用程序完全停止工作。

So I guess my first question is how do I make the switch-case "wait" until the data comes back before going to break .所以我想我的第一个问题是如何让switch-case “等待”直到数据返回,然后才会break

The second problem I have is that I ultimately want to be able to reuse my switch by wrapping it in a function where the page argument is the title of the page the user is navigating to and the callback will pass back the data returned from the getPageData function.我遇到的第二个问题是,我最终希望能够通过将它包装在一个函数中来重用我的switch ,其中page参数是用户导航到的页面的标题,并且回调将传回从getPageData返回的数据功能。 When I try this it results in an undefined error for the callback of the pageContentLoader function.当我尝试这样做时,它会导致pageContentLoader函数的回调出现undefined错误。

For the record, the getPageData in the code below is a separate function which performs a generic XMLHttpRequest.为了记录,下面代码中的getPageData是一个单独的函数,它执行一个通用的 XMLHttpRequest。 It's working fine because the data gets logged correctly in the callback.它工作正常,因为数据在回调中被正确记录。

pageContentLoader(page, function(data) {
                    console.log("Back with data ", data);   
});

function pageContentLoader(page, callback){
    var data;

            switch (page) {
                case 'contact':
                    console.log('contact in switch');
                    getPageData(page,function(data){
                      console.log("Contacts back! ", data);     
                    });             
                    break;    
                case 'blog':
                    console.log('blog in switch');
                    getPageData(page,function(data){
                        console.log("Posts back! ", data);      
                    });                 
                    break;    
                default:
                    alert('hey that page doesn't exist!');    
            } 
            callback(data); // results in callback undefined!!
}   

I am sure it is possible to make this work but I've tried everything I can find without any luck so far.我相信有可能完成这项工作,但到目前为止,我已经尝试了所有我能找到的方法,但没有任何运气。 If anyone has any pointers or wants to tell me what I am doing wrong within my code I'd be grateful!如果有人有任何指示或想告诉我我在代码中做错了什么,我将不胜感激!

Just ran into to this problem earlier, solved it as follows:刚刚遇到这个问题,解决方法如下:

async getResolvedPromises(myObject) {
    const promises = await Object.keys(myObject).map(async (k) => {
        switch (k) {
            case '1':
                const firstPromise = await asyncCallNumber1()
                return firstPromise
            case '2':
                const secondPromise = await asyncCallNumber2()
                return secondPromise
            case '3':
                const thirdPromise = await asyncCallNumber3()
                return thirdPromise
            default:
                return
        }
    })

    const data = await Promise.all(promises)
    return data
}

Here's a recent example in Typescript that I've adapted:这是我最近改编的 Typescript 中的一个示例:

private pageContentLoader = async (): Promise<any> => {
    try {
        switch(page) {
            case 'contact':
                return await getPageData(page).then((data) => {
                    console.log("Contacts back! ", data);
                    return data;
                })
            case 'blog':
                return await getPageData(page).then((data) => {
                    console.log("Posts back! ", data);
                    return data;
                })
            default:
                return 'Page does not exist';
        }   
    } catch (err) {
        throw err;
    }
}


private getPageContent = async () => {
    try {
        const contactPageData = await pageContentLoader('contact');
        const blogPageData = await pageContentLoader('blog');
    } catch (err) {
        throw err;
    }
};

Here's a solution using the Promise constructor:这是使用 Promise 构造函数的解决方案:

 pageContentLoader('blog').then(function(data) { console.log("Call to pageContentLoader results: ", data); }); function pageContentLoader(page) { switch (page) { case 'contact': return new Promise(function(resolve) { console.log('contact in switch'); getPageData(page).then(function(data) { console.log("pageContentLoader results: ",data); resolve(data) }); }); break; case 'blog': return new Promise(function(resolve) { console.log('blog in switch'); getPageData(page).then(function(data) { console.log("pageContentLoader results: ",data); resolve(data) }); }); break; default: return new Promise(function(resolve) { console.log('default in switch'); console.log("pageContentLoader results: doesn't exist"); resolve("page doesn't exist"); }); } } function getPageData(page) { return new Promise(function(resolve) { window.setTimeout(function() { console.log('getPageData executed') resolve(page); },2000); }); }

enter code here

For the first problem: You are trying to load a value of something that might not have been defined.对于第一个问题:您正在尝试加载可能尚未定义的值。 As said, you need to think about learning some tips and tricks of asynchronous coding but here's a solution :如前所述,您需要考虑学习一些异步编码的技巧和窍门,但这里有一个解决方案:

  switch (page) {
    case 'contact':
      alert('contact in switch');
      $.get(page +'.json').then(function(data){
        /* all the code AFTER fulfilling 
           the promise should BE here
         */
        handle_data(data);
      });
    break;

  //console.log("Response data: ", data); this should not be here
  ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM