2017-07-18 28 views
2

我無法用書面承諾Promise.all工作不正常

function requestsPlot(plot, info) { 
    return new Promise(function(resolve, reject) { 
    var plotObject = fieldsObject[plot] 
    var sqr = new Promise(function(resolve1, reject) { 
     debugger; 
     get(createSQRurl(plotObject.polygon)) 
     .then(function(result) { 
      plotObject.quality = sqrHtmlParsing(result); 
      resolve1(); 
     }); 
    }); 
    var soilType = new Promise(function(resolve2, reject) { 
     get(createSoilTypeUrl(plotObject.polygon)) 
     .then(function(result) { 
      plotObject.soilType = soilTypeHtmlParsing(result); 
      resolve2(); 
     }); 
    }); 
    var distance = new Promise(function(resolve3, reject) { 
     var start = turf.centerOfMass(plotObject.polygon).geometry.coordinates; 
     var end = info.homeCoords; 
     get('http://router.project-osrm.org/route/v1/driving/' + start + ';' + end + '?overview=false') 
     .then(function(result) { 
      var parsed = JSON.parse(result); 
      if (parsed.code == 'Ok') { 
      plotObject.distance = parsed.routes[0].distance/1000; 
      resolve3() 
      } else { 
      plotObject.distance = ''; 
      resolve3() 
      } 
     }); 
    }); 

    Promise.all([sqr, soilType, distance]).then(function() { 
     resolve('test'); 
    }) 
    }) 
} 

的想法是解析函數內的所有承諾(變量SQR,soilType後,由requestPlot函數返回的承諾異步函數距離)得到解決。但是,在get函數中的所有請求仍處於待定狀態時,該承諾已解決。請注意,'get'函數也返回一個承諾。 非常感謝您的幫助!

P.S.這裏是獲取功能

function get(url) { 
    var requestPromise = new Promise(function(resolve, reject) { 
    var req = new XMLHttpRequest(); 
    req.open('get', url); 

    req.onload = function() { 
     if (req.status == 200) { 
     resolve(req.response); 
     } 
     else { 
     reject(Error(req.statusText)); 
     } 
    }; 

    req.onerror = function() { 
     reject(Error("Network Error")); 
    }; 
    req.send(); 
    }); 
    return requestPromise 
} 

回答

6

承諾內的嵌套承諾是well-known anti-pattern

你不需要任何承諾構造函數,因爲你已經有get,它返回一個承諾,你可以直接使用它。

下面是你可以重新編寫代碼:

function requestsPlot(plot, info) { 

    const sqr = get(createSQRurl(plotObject.polygon)) 
    .then(sqrHtmlParsing); 

    const soilType = get(createSoilTypeUrl(plotObject.polygon)) 
    .then(soilTypeHtmlParsing); 

    const start = turf.centerOfMass(plotObject.polygon).geometry.coordinates; 
    const end = info.homeCoords; 
    const distance = get('http://router.project-osrm.org/route/v1/driving/' + start + ';' + end + '?overview=false') 
    .then(JSON.parse); 

    return Promise.all([sqr, soilType, distance]) 
    .then(([parsedSqr, parsedSoilType, parsedDistance]) => 
     Object.assign(plotObject, { 
     quality: parsedSqr, 
     soilType: parsedSoilType, 
     distance: parsedDistance.code == 'Ok' 
      ? parsed.routes[0].distance/1000 
      : '' 
     })) 
} 
+1

謝謝您的回答,這真的幫助我避免看這段代碼......哇感謝很多的超快速的答案,也爲 – smnbbrv

+0

關於反模式的鏈接! –

+0

@ChristophPahmeyer沒問題,很高興幫忙 – nem035