2015-04-17 32 views
5

Tôi có một lời hứa và tôi muốn nó giải quyết chỉ khi lời hứa bên trong đã được giải quyết. Ngay bây giờ nó giải quyết trước khi "giải quyết" chức năng đã đạt được trong "loadend" gọi lại.hứa hẹn giải quyết trước khi lời hứa bên trong giải quyết

Tôi đang thiếu gì? Tôi đang bối rối về cách bạn có nghĩa vụ phải sử dụng giải quyết và về cách bạn có thể sử dụng một lời hứa trong lời hứa khác.

Tôi không thể tìm thấy bất kỳ thứ gì đã trợ giúp trên web.

Trong ví dụ sau tôi về cơ bản tải một loạt các tệp, cho mỗi tệp tôi nhận được một đốm màu và tôi muốn chuyển đốm màu này trong trình đọc tệp.

Khi tất cả các tệp đã được chuyển đến trình đọc tệp, tôi muốn chuyển sang hàm tiếp theo trong chuỗi lời hứa.

Ngay bây giờ, nó chuyển sang chức năng tiếp theo trong chuỗi mà không cần chờ giải quyết được gọi.

var list = []; 
var urls = this.files; 

urls.forEach(function(url, i) { 
    list.push(
     fetch(url).then(function(response) { 
      response.blob().then(function(buffer) { 

       var promise = new Promise(
        function(resolve) { 

         var myReader = new FileReader(); 
         myReader.addEventListener('loadend', function(e) { 
          // some time consuming operations 
          ... 
          window.console.log('yo'); 
          resolve('yo'); 
         }); 

         //start the reading process. 
         myReader.readAsArrayBuffer(buffer); 
        }); 

       promise.then(function() { 
        window.console.log('smooth'); 
        return 'smooth'; 
       }); 

      }); 
     }) 
    ); 
}); 

... 

// run the promise... 
Promise 
    .all(list) 
    .then(function(message){ 
     window.console.log('so what...?'); 
    }) 
    .catch(function(error) { 
     window.console.log(error); 
    }); 

Trả lời

18

Khi bạn không return bất cứ điều gì từ then callbacks, nó giả định hoạt động đồng bộ và đi vào giải quyết sự hứa hẹn kết quả với kết quả (undefined) ngay lập tức.

Bạn cần return lời hứa từ mọi chức năng không đồng bộ, bao gồm then gọi lại mà bạn muốn bị xích.

Cụ thể, mã của bạn sẽ trở nên

var list = this.files.map(function(url, i) { 
//     ^^^^ easier than [] + forEach + push 
    return fetch(url).then(function(response) { 
     return response.blob().then(function(buffer) { 
      return new Promise(function(resolve) { 
       var myReader = new FileReader(); 
       myReader.addEventListener('loadend', function(e) { 
        … 
        resolve('yo'); 
       }); 
       myReader.readAsArrayBuffer(buffer); 
      }).then(function() { 
       window.console.log('smooth'); 
       return 'smooth'; 
      }); 
     }) 
    }); 
}); 

hoặc thậm chí tốt hơn, flattened:

var list = this.files.map(function(url, i) { 
    return fetch(url).then(function(response) { 
     return response.blob(); 
    }).then(function(buffer) { 
     return new Promise(function(resolve) { 
      var myReader = new FileReader(); 
      myReader.addEventListener('loadend', function(e) { 
       … 
       resolve('yo'); 
      }); 
      myReader.readAsArrayBuffer(buffer); 
     }); 
    }).then(function() { 
     window.console.log('smooth'); 
     return 'smooth'; 
    }); 
}); 
+0

tôi có hai chức năng mà cả hai quay trở lại một lời hứa mà đã lồng những lời hứa, (do thiết kế mô-đun) và vào cuối những lời hứa lồng nhau, tôi đã gọi quyết định của lời hứa chứa đựng nhưng cảm thấy rằng điều này là sai. Nhưng nhờ ví dụ của bạn, tôi đã có thể bỏ qua lời hứa có chứa, và chỉ trả lại chuỗi lời hứa lồng nhau. Điều này làm cho mã của tôi đẹp hơn rất nhiều để đọc. Tôi chỉ muốn cung cấp cho bạn ngón tay cái lên cho điều đó. – WORMSS

Các vấn đề liên quan