【问题标题】:How to declare a promise variable so that i can use it anywhere before promise gets resolved如何声明一个promise变量,以便在promise得到解决之前我可以在任何地方使用它
【发布时间】:2020-08-08 20:27:53
【问题描述】:

我在使用 Promise 解析代码之前遇到问题。

我有多个页面,哪个页面首先加载对我来说很难说,来自多个承诺的解析数据被所有开发人员使用。

这是我如何从多个承诺中获取解析数据

asyncCompletedPromise = Promise.all([getUserCollection(), getDefaultSettings(), getGroupUsersDetails()]).then((values) => {
  console.log('all promises are done');
  console.log(values);
  return values;
});

问题:如何将这个asyncCompletedPromise 变量作为基于promise 的变量,以便我可以在promise 被重新使用之前使用它。

这是工作演示:

var asyncCompletedPromise = Promise, apiCompletedTracker = {};

function getUserCollection(){
    return new Promise(function(resolve,reject){
        $.ajax({
            url: 'https://jsonplaceholder.typicode.com/users',
            type: 'GET',
            dataType:'json',
            success: function(data){
               console.log('getUserCollection api completed');
               apiCompletedTracker['getUserCollection'] = 'completed';
               resolve({user:data});
            }
        });
    });
}

function getDefaultSettings(){
   return new Promise(function(resolve,reject){
     $.ajax({
        url: 'https://jsonplaceholder.typicode.com/users',
        type: 'GET',
        dataType:'json',
        success: function(data){
            setTimeout(function(){
              console.log('getDefaultSettings api completed');
              apiCompletedTracker['getDefaultSettings'] = 'completed';
              resolve({default:data});
            },1500);
        }
    })
   });
}

function getGroupUsersDetails(){
   return new Promise(function(resolve,reject){
     $.ajax({
        url: 'https://jsonplaceholder.typicode.com/posts',
        type: 'GET',
        dataType:'json',
        success: function(data){
            setTimeout(function(){
              console.log('getGroupUsersDetails api completed');
              apiCompletedTracker['getGroupUsersDetails'] = 'completed';
              resolve({group:data});
            },2500);
        }
    })
   });
}

// when all of the above function completes i can apply 


asyncCompletedPromise = Promise.all([getUserCollection(), getDefaultSettings(), getGroupUsersDetails()]).then((values) => {
  console.log('all promises are done');
  //console.log(values);
  return values;
});


asyncCompletedPromise.then(function(values){
   console.log('variable used first time');
});


asyncCompletedPromise.then(function(values){
   console.log('variable used second time');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

当我在所有承诺 Promise.all() 被解析之前使用 asyncCompletedPromise 变量时,代码给出错误

var asyncCompletedPromise = Promise, apiCompletedTracker = {};

function getUserCollection(){
    return new Promise(function(resolve,reject){
        $.ajax({
            url: 'https://jsonplaceholder.typicode.com/users',
            type: 'GET',
            dataType:'json',
            success: function(data){
               console.log('getUserCollection api completed');
               apiCompletedTracker['getUserCollection'] = 'completed';
               resolve({user:data});
            }
        });
    });
}

function getDefaultSettings(){
   return new Promise(function(resolve,reject){
     $.ajax({
        url: 'https://jsonplaceholder.typicode.com/users',
        type: 'GET',
        dataType:'json',
        success: function(data){
            setTimeout(function(){
              console.log('getDefaultSettings api completed');
              apiCompletedTracker['getDefaultSettings'] = 'completed';
              resolve({default:data});
            },1500);
        }
    })
   });
}

function getGroupUsersDetails(){
   return new Promise(function(resolve,reject){
     $.ajax({
        url: 'https://jsonplaceholder.typicode.com/posts',
        type: 'GET',
        dataType:'json',
        success: function(data){
            setTimeout(function(){
              console.log('getGroupUsersDetails api completed');
              apiCompletedTracker['getGroupUsersDetails'] = 'completed';
              resolve({group:data});
            },2500);
        }
    })
   });
}

// Note below line, i want to use it somewhere before it is actually resolved
asyncCompletedPromise.then(function(values){
   console.log('called before all promises are resolved,giving error, error should not happen irrespective calling it anywhere');
});

// when all of the above function completes i can apply


asyncCompletedPromise = Promise.all([getUserCollection(), getDefaultSettings(), getGroupUsersDetails()]).then((values) => {
  console.log('all promises are done');
  //console.log(values);
  return values;
});


asyncCompletedPromise.then(function(values){
   console.log('variable used first time');
});


asyncCompletedPromise.then(function(values){
   console.log('variable used second time');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

【问题讨论】:

  • 您在此处尝试解决的更高级别的问题是什么,这会使您需要在定义承诺之前访问它?
  • 您执行promise.all,完成后执行then。如果你想在promise完成之前做某事,不要使用then
  • @charlietfl,我正在与多个开发人员合作,他们可能会在承诺真正得到解决之前使用它们,我想解决这个问题
  • "beforesolved"到底要做什么?这听起来真的很像XY Problem。您还混淆了示例中定义和解析的概念
  • 任何放在Promise.all之后的函数都会在promise解决之前运行(当然如果它不是另一个promise)

标签: javascript jquery promise


【解决方案1】:

这与承诺无关。在给它赋值之前,你不能使用这个变量,点。

请注意,即使在您的第一个工作 sn-p 中,您也是在使用 ajax 响应异步实现它所持有的承诺之前使用该变量。

【讨论】:

  • 我想asyncCompletedPromise 声明为promise 类型的全局变量,这就是我的问题所在,即使声明的 promise 类型变量也是一种观察者,我可以在任何地方使用它跨度>
  • 是的,与所有全局变量一样,您需要将初始化代码放在使用代码之前。为什么将asyncCompletedPromise = Promise.all([getUserCollection(), getDefaultSettings(), getGroupUsersDetails()]) 移到脚本顶部会出现问题?
  • 现在我的问题是,无论在任何地方调用它,我如何才能在全局 asyncCompletedPromise 变量上 watch
  • 或者你会建议在这些数据上使用setInterval to watch
  • 等等,你的actual problem是什么?再说一次,为什么你不能把 Promise 初始化放在最前面呢?实际上是否涉及多个脚本?不,你不能/不应该看变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-05
  • 2019-05-28
  • 1970-01-01
相关资源
最近更新 更多