【问题标题】:Making a promise work inside a JavaScript switch/case在 JavaScript 开关/案例中做出承诺
【发布时间】:2016-10-21 21:45:32
【问题描述】:

我遇到了一个问题(如果我说实话,有两个问题)在 switch-case 中获得承诺或回调。这是基本代码。

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

我知道,由于异步函数的性质,在数据返回之前切换到break,使data 记录为undefined。所以我认为将break 放在回调中会起作用,但它不起作用。当我这样做时,应用程序完全停止工作。

所以我想我的第一个问题是如何让switch-case“等待”直到数据返回后再转到break

我遇到的第二个问题是,我最终希望能够重用我的switch,方法是将其包装在一个函数中,其中page 参数是用户导航到的页面的标题,回调将通过返回从getPageData 函数返回的数据。当我尝试这样做时,它会导致pageContentLoader函数的回调出现undefined 错误。

为了记录,下面代码中的getPageData是一个单独的函数,它执行一个通用的XMLHttpRequest。它工作正常,因为数据在回调中正确记录。

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!!
}   

我确信可以完成这项工作,但到目前为止我已经尝试了所有我能找到的东西,但没有任何运气。如果有人有任何指示或想告诉我我在代码中做错了什么,我将不胜感激!

【问题讨论】:

  • 任何带有 Promise 的东西都必然是异步的 - 因此你试图在 data 被填充之前记录它......并且...... data 无论如何都是回调函数的参数,所以它是与您之前声明的 data 不一样 ...您需要了解范围和异步编码 .... to wait until the data comes back,您不能,您需要完全重新考虑您的代码
  • 在第二个代码 sn-p 中,调用 getPageData 回调中的回调
  • 我知道并理解它是异步的。我的问题是让承诺的异步性质在switch case 中工作,而不会落入break。我知道data 没有记录,因为它还没有回来。这就是我要解决的问题。感谢您的意见!
  • @mikeym 您需要将您的开关放入异步回调中,然后执行它。你不能使用你没有的数据。
  • @mikeym 没问题。有时事情只需要改写。

标签: javascript callback switch-statement


【解决方案1】:

刚刚遇到这个问题,解决方法如下:

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
}

【讨论】:

    【解决方案2】:

    这是我最近改编的 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;
        }
    };
    

    【讨论】:

      【解决方案3】:

      这是一个使用 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
      

      【讨论】:

        【解决方案4】:

        对于第一个问题: 您正在尝试加载可能尚未定义的值。 如前所述,您需要考虑学习一些异步编码的技巧和窍门,但这里有一个解决方案:

          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
          ...
        

        【讨论】:

        • 您应该释放任何依赖且有效且仅在通过ajax响应导入数据后才有效的操作应该在成功函数的块内(函数通过then)。
        猜你喜欢
        • 2015-11-24
        • 2017-03-09
        • 1970-01-01
        • 1970-01-01
        • 2017-06-18
        • 2014-05-07
        • 2016-12-02
        • 1970-01-01
        相关资源
        最近更新 更多