2016-04-25 30 views
5

Tôi thường thấy trong các tài liệu của người khác như sau:JavaScript - Trả lời lời hứa VÀ/HOẶC gọi lại cuộc gọi?

Gọi lại là tùy chọn, nếu bỏ qua trả về lời hứa.

Đây là những gì tôi có:

export function doSomeAsync(options, callback) { 

    const useCallback = (callback && typeof callback == 'function'); 

    const promise = new Promise((resolve, reject) => { 

     // --- do async stuff here --- 
     const check = (options.num === 1) ? true : false; 
     setTimeout(() => { 
      if (check) { 
       finish(true, "Number is 1"); 
      } else { 
       finish(false, new Error("Number is not 1")); 
      } 
     }, 1000); 
     // --------------------------- 

     function finish(ok, rtn) { 
      if (useCallback) { 
       if (ok) { 
        callback(null, rtn); 
       } else { 
        callback(rtn, null); 
       } 
      } else { 
       if (ok) { 
        resolve(rtn); 
       } else { 
        reject(rtn); 
       } 
      } 
     } 

    }); 

    return (useCallback) ? false : promise; 
} 

Chức năng finish() chỉ tránh được rất nhiều if... tuyên bố rải rác xung quanh.

Tôi đang tạo đối tượng lời hứa, cho dù tôi có sử dụng hay không.

kiểm tra như thế này:

doSomeAsync({ num: 1 }).then((result) => { 
    console.log('p result', result); 
}).catch((err) => { 
    console.log('p err', err); 
}); 

doSomeAsync({ num: 1 }, (err, result) => { 
    if (err) { 
     console.log('cb err', err); 
    } else { 
     console.log('cb result', result); 
    } 
}); 

này hoạt động, nhưng tôi đang tự hỏi nếu điều này là cách tốt nhất, hoặc nếu người khác có thực hiện tốt hơn và gọn gàng hơn ..?

+0

Có thể phù hợp hơn cho http://codereview.stackexchange.com/ – Andy

+1

Bạn đang sử dụng thư viện lời hứa nào? Bluebird thậm chí có [một chức năng chuyên dụng] (http://bluebirdjs.com/docs/api/ascallback.html) cho việc này. – Bergi

+0

Tôi đang chạy Node v4.2.2, với Babel cho ES6 ('babel-preset-es2015 6.6.0'), nhưng tôi chưa cài đặt ployfill cụ thể cho lời hứa. Vì vậy, bản địa Node hứa hẹn tôi đoán. –

Trả lời

10

này có thể được đơn giản nếu bạn chỉ đơn giản là luôn được sử dụng lời hứa, mà bạn tôi luôn tạo anyway:

export function doSomeAsync(options, callback) { 
    const promise = new Promise((resolve, reject) => { 
     const check = (options.num === 1) ? true : false; 
     setTimeout(() => { 
      if (check) { 
       resolve("Number is 1"); 
      } else { 
       reject(new Error("Number is not 1")); 
      } 
     }, 1000); 
    }); 

    if (callback && typeof callback == 'function') { 
     promise.then(callback.bind(null, null), callback); 
    } 

    return promise; 
} 

Chức năng của bạn luôn luôn hứa hẹn dựa vào, còn trong thực tế là nó luôn luôn trả về một lời hứa. Người gọi chỉ đơn giản là miễn phí để bỏ qua điều đó. Đối số gọi lại chỉ đơn thuần là "giao diện dự phòng kế thừa" (hoặc "giao diện thay thế" nếu bạn thích) để sử dụng lời hứa đó.

+2

Vâng, đây chính là cách tiếp cận mà tôi đang suy nghĩ. Trả về 'false' có vẻ hơi lãng phí - cũng (là một .NET dev cũng như JS) có vẻ lạ khi trả về hai kiểu khác nhau từ một hàm như vậy. –

+0

Cảm ơn lừa dối ... Tôi đã cập nhật câu hỏi của mình với các cuộc gọi thử nghiệm. Sau khi cập nhật để sử dụng mã của bạn, tôi nhận được: 'p result Number là 1' và' cb err Number là 1'. Hiện các cuộc gọi lại chỉ có một param? –

+0

@Stephen Trong ví dụ của tôi ở trên, cách các lời gọi lại 'promise.then' bị ràng buộc,' callback' sẽ nhận được một đối số trong trường hợp thành công và hai đối số ('false' và error) trong trường hợp thất bại. Gọi lại dự kiến ​​sẽ có một chữ ký của 'hàm (kết quả, err)'. Thiết kế giao diện đó theo bất kỳ cách nào bạn muốn. – deceze

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