2014-10-28 26 views
36

Đây là phiên bản ngắn của mã của tôi.nếu có khác hứa hẹn (bluebird)

var Promise = require('bluebird'); 
var fs = Promise.promisifyAll(require("fs")); 

if (conditionA) { 
    fs.writeFileAsync(file, jsonData).then(function() { 
    return functionA(); 
    }); 
} else { 
    functionA(); 
} 

Cả hai điều kiện đều gọi functionA. Có cách nào để tránh tình trạng khác không? Tôi có thể làm fs.writeFileSync nhưng tôi đang tìm một giải pháp không chặn.

+0

Hứa hẹn được thiết kế để điều khiển tác vụ không đồng bộ. Tại sao sử dụng fucntion đồng bộ? Bạn có thể chỉ cần kiểm tra giá trị trả về của 'writeFileAsync'. – CodeColorist

Trả lời

52

Tôi nghĩ rằng bạn đang tìm kiếm

(conditionA 
    ? fs.writeFileAsync(file, jsonData) 
    : Promise.resolve()) 
.then(functionA); 

đó là viết tắt của

var waitFor; 
if (conditionA) 
    waitFor = fs.writeFileAsync(file, jsonData); 
else 
    waitFor = Promise.resolve(undefined); // wait for nothing, 
              // create fulfilled promise 
waitFor.then(function() { 
    return functionA(); 
}); 
2

Bạn luôn có thể sử dụng Promise.all() với chức năng có điều kiện

var condition = ...; 

var maybeWrite = function(condition, file, jsonData){ 
    return (condition) ? fs.writeFileAsync(file, jsonData) : Promise.resolve(true); 
} 

Promise.all([maybeWrite(condition, file, jsonData),functionA()]) 
.then(function(){ 
    // here 'functionA' was called, 'writeFileAsync' was maybe called 
}) 

Hoặc, nếu bạn muốn functionA chỉ được gọi sau khi tệp có thể được viết, bạn có thể tách riêng:

maybeWrite(condition, file, jsonData) 
.then(function(){ 
    // here file may have been written, you can call 'functionA' 
    return functionA(); 
}) 
+0

Vấn đề * duy nhất của tôi với cách tiếp cận này là khả năng bảo trì. Bạn đăng ký cho mình để có 'untangle' công cụ xuống dòng. Đó là một trong những lợi ích của chuỗi lời hứa - logic của bạn là cảm giác tuyến tính. –

7

Trong khi các đề xuất khác ở đây hoạt động, cá nhân tôi thích những điều sau đây.

Promise.resolve(function(){ 
    if (condition) return fs.writeFileAsync(file, jsonData); 
}()) 
.then() 

Điều bất lợi là tạo ra lời hứa bổ sung này (thay vì IMO nhỏ) nhưng trông sạch sẽ hơn nhiều. Bạn cũng có thể thêm các điều kiện/logic khác một cách dễ dàng bên trong IIFE.

EDIT

Sau khi thực hiện điều như thế này trong một thời gian dài bây giờ tôi đã chắc chắn đã thay đổi một cái gì đó hơi rõ ràng hơn. Lời hứa ban đầu được tạo ra bất kể vì thế nó là rõ ràng hơn để chỉ cần làm:

/* Example setup */ 
 

 
var someCondition = (Math.random()*2)|0; 
 
var value = "Not from a promise"; 
 
var somePromise = new Promise((resolve) => setTimeout(() => resolve('Promise value'), 3000)); 
 

 

 
/* Example */ 
 

 
Promise.resolve() 
 
.then(() => { 
 
    if (someCondition) return value; 
 
    return somePromise; 
 
}) 
 
.then((result) => document.body.innerHTML = result);
Initial state
Trên thực tế, trong trường hợp của bạn nó sẽ chỉ đơn giản là

if (someCondition) return somePromise; 

bên trong .Sau đó đầu tiên() chức năng.

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