微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

等待JS异步功能完成,然后再运行一些同步代码

如何解决等待JS异步功能完成,然后再运行一些同步代码

我有一个异步函数getDataItem,该函数返回一个promise并将数据传递给另一个函数preparePhysicianSchemaData,该函数从传递的数据以及调用获取的数据中构建全局对象physicianDetailsObj对于最初传递的每一行数据,它内部还有一个异步函数

getDataItem(listID,itemID).then(preparePhysicianSchemaData)

仅在完全填充全局对象变量physicianDetailsObj之后,才需要调用一个名为buildSEOSchemaBlock()函数,该函数的作用是解析physicianDetailsObj对象并构建所需的最终对象。

我宁愿不使用setTimeOut尝试计时:

      setTimeout(function(){ return getListItem(listID,itemID).then(preparePhysicianSchemaData) },10);
      setTimeout(function(){ return buildPhysicianSchemaBlock() },3000); 

我如何像这样链接最后一个函数getDataItem(listID,itemID).then(preparePhysicianSchemaData).then(buildPhysicianSchemaBlock)确保仅在完全填充全局对象变量physicianDetailsObj之后运行最后一个函数

    var physicianDetailsObj = {};
    function getListItem() {}  //returns promise
    function preparePhysicianSchemaData(item) {
        var tempPhysicianDetailsObj = {};   
        var currentPhysicianItemId = item.get_id();
    
        tempPhysicianDetailsObj = {
            "name" : item.get_item("Title"),"url" : item.get_item("SEOCanonicalHref").match('href="([^"]+)')[1]
        };
     
         var currentItemPhysicianTag= item.get_item("PhysicianItemTag").get_label();  
    
         getPhysicianLocationDetailsFromServiceLocations(currentItemPhysicianTag).then(function(slitems) {
            console.log(slitems);
            var slitemEnum = slitems.getEnumerator();
    
            //first empty the object
            Object.keys(physicianDetailsObj).forEach(k => delete physicianDetailsObj[k]);
    
            while (slitemEnum.moveNext()) {
                var slitem = slitemEnum.get_current();
                physicianDetailsObj[currentPhysicianItemId + '-' + slitem.get_id()] = {
                    "name":  tempPhysicianDetailsObj["name"],"image": tempPhysicianDetailsObj["image"],"url": tempPhysicianDetailsObj["url"],"streetAddress": slitem.get_item("LocationAddress"),"addressLocality": slitem.get_item("LocationLU_x003A_LocationCity").get_lookupValue()
                }
            }
         }); 
    
    }

function buildSEOSchemaBlock(){ }  //process physicianDetailsObj

getPhysicianLocationDetailsFromServiceLocations一个异步函数,在preparePhysicianSchemaData

内部被调用

解决方法

如果preparePhysicianSchemaData是同步的,则不需要等待它,只需在它之后执行操作即可。像这样:

getListItem(listID,itemID).then(function() {
  preparePhysicianSchemaData();
  buildPhysicianSchemaBlock();
});

或者如果您需要Promise的结果,例如:

getListItem(listID,itemID).then(function(result) {
  preparePhysicianSchemaData(result);
  buildPhysicianSchemaBlock();
});

如果它是异步,则可以链接Promises,类似于:

getListItem(listID,itemID)
  .then(function(result) { return preparePhysicianSchemaData(result); })
  .then(function(newResult) { return buildPhysicianSchemaBlock(newResult); });

基本上,每次对.then()的调用都会将先前Promise的结果传递给新的异步函数,并返回该函数的Promise。

,

如果您需要严格按照顺序执行功能,请使用async / await和Promises,看看此演示

// Use async
(async () => {
  // Function 1
  const fn1 = (val) => {
    return new Promise((resolve,reject) => {
      // Do some stuff here
      val = val + 1;
      // Resolve result.
      // Can be resolved from any level
      // of nested function!
      function nested1() {
        function nested2() {
          resolve(val);
        }
        nested2();
      }
      nested1();
    });
  };
  
  // Function 2
  const fn2 = (val) => {
    return new Promise((resolve,reject) => {
      // Do some stuff here
      val = val * 2;
      // Resolve result
      resolve(val);
    });
  };
  
  // Function 3
  const fn3 = (val) => {
    return new Promise((resolve,reject) => {
      // Do some stuff here
      val = val + 1000;
      // Resolve result
      resolve(val);
    });
  };
  
  // Async code
  let val = 5;
  
  val = await fn1(val); // Wait until fn1 resolves
  val = await fn2(val); // Wait until fn2 resolves
  val = await fn3(val); // Wait until fn3 resolves
  
  console.log(val);
})();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。