顺序链接来自2个独立函数的承诺

时间:2018-03-14 11:57:28

标签: javascript promise html-framework-7

我已经审核了所有相关主题,但由于某种原因,我无法理解解决我的案例的正确语法。 它是Framework7平台上的Javascript。

有一个函数内部有$ .each,它循环遍历一个项目数组并执行异步POST操作来更新该项目。 需要更新两个不同位置的项目,所以我执行此函数两​​次,每次都有不同的参数。

在序列中将这两个函数链接在一起以便能够重新加载页面的最佳方法是什么,因为所有异步请求都已执行?

提前谢谢!

更新<!/强>

我设法做到这一点,但承诺。然后没有导致&#34;成功&#34;:

var tasks = [1,2,3];
var docs = [3,4,5];
var functions = [asyncOperation(tasks),asyncOperation(docs)]

var asyncOperation = function(items) {
 return new Promise(function (resolve, reject) {
   var deferreds = [];
   items.forEach(function(i,e){
   deferreds.push(
       app.request({
       url: buildurlnew,
       type: "POST",
       headers: buildheader,
       contentType: "application/json;odata=verbose",
       data: JSON.stringify(UpdatePayload),
       success: function (data) {},
       error: function(xhr, textStatus, errorThrown ) {}
   )
   });
   return deferreds;
});
}

var promises = Promise.all(functions);
promises.then(function(results) {
//console.log("Success");
});

更新2 - 根据建议更改的代码

var processtasks = function(array, dig) {
   var getlistname = GetItemTypeForListName("Alerts")
   var itemProperties = {'Title' :"Test"};
   var UpdatePayload = {'__metadata': {'type': getlistname}};
   for(var prop in itemProperties){
      UpdatePayload[prop] = itemProperties[prop]
   }
   var buildurl = "<REST URL to Sharepoint list>"
   var buildheader = { "Accept": "application/json;odata=verbose", "X-RequestDigest" : dig, "X-HTTP-Method": "MERGE", "If-Match": "*"}
   return Promise.all(array.map(function(item) {
      buildurlnew = buildurl+"("+item+")";
      return app.request({
         url: buildurlnew,
         type: "POST",
         headers: buildheader,
         contentType: "application/json;odata=verbose",
         data: JSON.stringify(UpdatePayload),
         success: function (data) {},
         error: function(xhr, textStatus, errorThrown) {}
      });
   }));
}

var processitems = function(listName, array, dig, type, source, web) {
   var getlistname = GetItemTypeForListName(listName)
   var buildurl = "<REST URL to Sharepoint list>"
   var buildheader = { "Accept": "application/json;odata=verbose", "X-RequestDigest" : dig, "If-Match": "*"}
   return Promise.all(array.map(function(item) {
      var itemProperties = {'UserId' : app.data.UserID, 'Title' : item};
      var UpdatePayload = {'__metadata': {'type': getlistname}};
      for(var prop in itemProperties){
         UpdatePayload[prop] = itemProperties[prop]
      }
      return app.request({
          url: buildurl,
          type: "POST",
          headers: buildheader,
          contentType: "application/json;odata=verbose",
          data: JSON.stringify(UpdatePayload),
          success: function (data) {},
          error: function(xhr, textStatus, errorThrown ) {}
      });
   }));
}

processitems(listName, array, dig, type, source, web).then(function(r1) {
   return processtasks(ids,dig);
}).then(function(r2) {
   console.log(r2);
}).catch(function(err) {
   console.log(err);
});

1 个答案:

答案 0 :(得分:1)

首先,您必须修复asyncOperation()函数,因为它未正确返回与您正在执行的基础异步操作相关联的承诺。

这段代码没有多大意义。你有一个基本的结构:

var asyncOperation = function(items) {
    return new Promise(function(resolve, reject) {
        // body of function here
    });
}

到目前为止一切顺利。但是,你需要在promise承诺函数内执行的操作是启动一些异步操作,并在完成后调用resolve或reject。你不是那样做的。因此,您的承诺永远不会解决或拒绝。

相反,您将从promise执行器回调中返回一个延迟的数组,它不会执行任何操作。 promise executor函数不期望任何返回值,因此从它返回一个值什么都不做。您必须通过调用resolve(...)reject(...)来指示在promise执行程序中完成异步操作。

如果app.request()返回承诺,那么您甚至根本不需要做出自己的承诺。你可以这样做:

var asyncOperation = function(items) {
    return Promise.all(items.map(function(item) {
        return app.request(...);
    }));
}

asyncOperation(...).then(function(results) {
    // all done here
}).catch(function(err) {
    // error here
});

items.map()生成一个promises数组,Promise.all()返回一个新的单一promise,监视该promise数组,并在数组中的所有promise解析或拒绝任何一个promise时拒绝。

如果app.request()没有返回承诺,那么你可能应该制作一个“promisified”版本,这样你就可以使用Promise.all()等承诺函数,也许使用util.promisify()

要并行运行其中两个(这似乎很实用,因为它们似乎并不相互依赖),你可以这样做:

然后,一旦你正确地返回你的函数的承诺,如果你有两个这样的承诺,你可以在多个函数调用上使用Promise.all()

Promise.all([asyncOperation(...), asyncOperation(...)]).then(function(results) {
    // both done here
    // not the result may be an array of arrays
}).catch(function(err) {
    // error here
});
  

将这两个函数按序列链接在一​​起的最佳方法是什么?

要按顺序运行它们,您可以执行以下操作:

asyncOperation(args1).then(function(r1) {
    return asyncOperation(args2);
}).then(function(r2) {
    console.log(r2);
}).catch(function(err) {
    console.log(err);
});