All nesting cannot guarantee the order of Promise.all execution in the inner layer.

  node.js, question

1. Use nodejs. The outer layer includesvar enter = Promise.all([Promise.all([innerPromise...])...]).then(console.log("problem happend"))Nesting to parse two-dimensional data, inner array ofinnerPromiseIn fact is also a.startPromise.then(return secendPromise)Structure. ResultsecendPromiseIn the outer layerPromise.all FulfilledAfter the implementation. Namelyproblem happendWill be insecendPromiseIt was exported before it was executed. Does not Promise.all have to be fully filled before the promise array is fully filled?

2. Specific examples are as follows. Input data type is as follows [[cat, [nameid1, nameid2, nameid3 …]] …], cat corresponds to multiple nameids. This two-dimensional data uses two Promise.all nested parsing. The execution result is the first step of the database operation. After the completion of insertCategoryAttrName, the client is closed, and subsequent query and insert operations cannot be completed.

function dbInsert(catAttrMap,client){
 var taskArray = Array.from(catAttrMap);
 //the outer array uses Promise.all
 var promiseArray = taskArray.map(function(value,index){
 var categoryId = value[0];
 var attibuteNameIdPromiseArray = Array.from(value[1]);
 attibuteNameIdPromiseArray.map(function(attrinameId,sortValue){
 //Promise Data Operation Chain
 return insertChain(categoryId,attrinameId,sortValue)
 })
 //After the inner set is fully satisfied with a Promise.all
 return Promise.all(attibuteNameIdPromiseArray);
 })
 return  Promise.all(promiseArray).finally(function(){
 client.end();  //database resource release
 });
 bracket
 
 /*
 * database asynchronous operation chain
 * 1. insertCategoryAttrName returns categoryId after inserting into the database.
 * 2. Then getAttributeValuesByNameId queries the database to obtain the attriValueId array
 * 3. According to categoryId, attriValueId is inserted into the database.
 */
 function insertChain(categoyId,attrinameId,sortValue){
 return insertCategoryAttrName(categoyId,attrinameId,sortValue,"1")
 .then(function(cateAttNameId){
 AttributeCounter plus;
 return getAttributeValuesByNameId(attrinameId).then(function(attriValueIdObjectArray){
 Console.log ("attribute value group size:" plus attriValueIdObjectArray.length ");
 var attributeInsertPromiseArr = attriValueIdObjectArray.map(function(attributeIdObject,index){
 return insertCategoryAttrValue(cateAttNameId,attributeIdObject.id,index).then(function(){
 ValueCounter plus;
 });
 })
 return Promise.all(attributeInsertPromiseArr);
 });
 }).then(function(){
 console.log("right time?"  )
 })
 bracket
 
 function insertCategoryAttrName(args..){
 return new Promise(..)
 bracket
 
 function getAttributeValuesByNameId(args..){
 return new Promise(..)
 bracket
 
 function insertCategoryAttrValue(args..){
 return new Promise(..)
 bracket

3. My side suspects that it has something to do with the mechanism of Promise.all, so I expand the two-dimensional array of dbInsert into one-dimensional array, and use a layer of Promise.all to find that client can be closed at the right time.

/**
 * First expand according to attribute Set.  Flattens the entire cate-attributeName array
 */
 
 function dbInsertPlain(catAttrMap){
 var taskArray = Array.from(catAttrMap);
 Log ("category size" plus taskArray.length);
 var skretch = new Array();
 
 taskArray.forEach(function(currentValue){
 var categoryId = currentValue[0];
 var nameIdArray = Array.from(currentValue[1]);
 nameIdArray.forEach(function(value,index){
 skretch.push([categoryId,value,index])
 })
 })
 
 var promiseArray = skretch.map(function(value,index){
 let categoryId = value[0];
 let attrinameId = value[1];
 let sortValue = value[2];
 return insertChain(categoryId,attrinameId,sortValue)
 })
 //use the expanded Promise.all
 return  Promise.all(promiseArray).finally(function(){
 client.end();
 });
 bracket

4. Therefore, it can be basically judged that Promise.all nest caused the perception of then’s execution state behind insertCategoryAttrName. The specific reason is still not clear, ask expert advice.

5. The local test was carried out using setTimeout simulation scenario .. Well, the code writing problem .. Promise.all in the inner layer of the insertChain method did not return at all .. However, taking this opportunity to see the source code of Promise is also a harvest.

var *attibuteNameIdArray* = Array.from(value[1]);
 var *attibuteNameIdPromiseArray* = *attibuteNameIdArray*.map(function(attrinameId,sortValue){
 //Promise Data Operation Chain
 return insertChain(categoryId,attrinameId,sortValue)
 })
 //After the inner set is fully satisfied with a Promise.all
 return Promise.all(*attibuteNameIdPromiseArray*);

Analog code

This is the code of the local test, if you are interested, you can look at the execution. bluebird used by Promise requires npm to install the dependency first.

Please enter the code var Promise = require('bluebird');
 
 function getInner(value){
 return  new Promise(function(resolve,reject){
 setTimeout(function(value){
 resolve(value);
 },1000,[value, "don't understand", "what"]);
 })
 bracket
 
 function lastAync(value){
 return  new Promise(function(resolve,reject){
 setTimeout(function(value){
 resolve(value);
 },1000,value);
 })
 bracket
 
 // console.log(getInner());  b
 
 function getPromise(){
 return new Promise(function(resolve,reject){
 setTimeout(function(){
 Log ("tier 1");
 Resolve ("do not search");
 // resolve("pp");
 
 },1000);
 })
 bracket
 
 function lala(){
 return getPromise()
 .then(function(x){
 console.log(x)
 return getInner(x).then(function(thirdArray){
 // console.log("ks");
 var ksArray = thirdArray.map(function(value,index){
 // console.log(value);
 return lastAync(value);
 })
 return Promise.all(ksArray);
 });
 }).then(function(t){
 console.log(t);
 }).then(function(k){
 Console.log ("hello");
 })
 bracket
 
 
 function TurnAround(singger){
 this.singing = singger;
 bracket
 
 var t = [["1",["a","b","c","d"]],["2",["xx","yy","zz","dd"]]];
 
 
 function test(){
 
 var tArray = t.map(function(value,index){
 var innerArray = value[1];
 var inPA = innerArray.map(function(value,index){
 return lala();
 })
 return Promise.all(inPA);
 })
 return Promise.all(tArray).finally(function(){
 Log ("interrupt");
 });
 bracket
 
 
 test();