Поиск…


замечания

Обещания имеют состояние, они начинаются как ожидающие и могут решить:

  • выполнил это означает , что вычисление успешно завершено.
  • отклоненное значение означает, что вычисление потерпело неудачу.

Обещающие функции возврата никогда не должны бросать , вместо этого они должны возвращать отклонения. Бросание из функции возврата обещания заставит вас использовать как a } catch { и .catch . Люди, использующие обещанные API, не ожидают обещаний бросить. Если вы не знаете, как работают асинхронные API-интерфейсы в JS, сначала см. Этот ответ .

Преобразование всего модуля NodeJS сразу

Допустим, у вас есть библиотека, которая возвращает обратные вызовы, например, модуль fs в NodeJS:

const fs = require("fs");
fs.readFile("/foo.txt", (err, data) => {
  if(err) throw err;
  console.log(data);
});

Мы хотим преобразовать его в API API с обещаниями, с помощью promisifyAll - мы можем сделать это с помощью promisifyAll который преобразует весь API для использования обещаний:

const Promise = require("bluebird");
const fs = Promise.promisifyAll(require("fs"));
// this automatically adds `Async` postfixed methods to `fs`.
fs.readFileAsync("/foo.txt").then(console.log);

Это позволяет использовать весь модуль в качестве обещаний.

Вот некоторые общие примеры того, как обещать определенные модули:

// The most popular redis module
var Promise = require("bluebird");
Promise.promisifyAll(require("redis"));
// The most popular mongodb module
var Promise = require("bluebird");
Promise.promisifyAll(require("mongodb"));
// The most popular mysql module
var Promise = require("bluebird");
// Note that the library's classes are not properties of the main export
// so we require and promisifyAll them manually
Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);
// Mongoose
var Promise = require("bluebird");
Promise.promisifyAll(require("mongoose"));
// Request
var Promise = require("bluebird");
Promise.promisifyAll(require("request"));
// Use request.getAsync(...) not request(..), it will not return a promise
// mkdir
var Promise = require("bluebird");
Promise.promisifyAll(require("mkdirp"));
// Use mkdirp.mkdirpAsync not mkdirp(..), it will not return a promise
// winston
var Promise = require("bluebird");
Promise.promisifyAll(require("winston"));
// rimraf
var Promise = require("bluebird");
// The module isn't promisified but the function returned is
var rimrafAsync = Promise.promisify(require("rimraf"));
// xml2js
var Promise = require("bluebird");
Promise.promisifyAll(require("xml2js"));
// jsdom
var Promise = require("bluebird");
Promise.promisifyAll(require("jsdom"));
// fs-extra
var Promise = require("bluebird");
Promise.promisifyAll(require("fs-extra"));
// prompt
var Promise = require("bluebird");
Promise.promisifyAll(require("prompt"));
// Nodemailer
var Promise = require("bluebird");
Promise.promisifyAll(require("nodemailer"));
// ncp
var Promise = require("bluebird");
Promise.promisifyAll(require("ncp"));
// pg
var Promise = require("bluebird");
Promise.promisifyAll(require("pg"));

Преобразование одной функции NodeJS

Вы можете преобразовать одну функцию с аргументом обратного вызова в версию Promise -returning с Promise.promisify , чтобы это:

const fs = require("fs");
fs.readFile("foo.txt", (err, data) => {
   if(err) throw err;
   console.log(data);
});

будет выглядеть так:

const promisify = require("bluebird");
const readFile = promisify(require("fs").readFile));
readFile("foo.txt").then(console.log); // promisified version

Преобразование любого другого API обратного вызова

Чтобы конвертировать любой API обратного вызова в обещания, предполагая, что promisify и promisifyAll не подходит, вы можете использовать конструктор обещаний .

Создание обещаний в целом означает указание, когда они устанавливаются - это означает, что они переходят на выполненную (завершенную) или отклоненную (ошибочную) фазу, чтобы указать, что данные доступны (и к ним можно получить доступ. .then ).

new Promise((fulfill, reject) => { // call fulfill/reject to mark the promise
   someCallbackFunction((data) => {
      fulfill(data); // we mark it as completed with the value
   })
});

В качестве примера давайте преобразуем setTimeout для использования обещаний:

function delay(ms) { // our delay function that resolves after ms milliseconds
  return new Promise((resolve, reject) => { // return a new promise
    setTimeout(resolve, ms); // resolve it after `ms` milliseconds have passed
  })
}
// or more concisely:
const delay = ms => new Promise(r => setTimeout(r, ms));

Теперь мы можем использовать его, как обычную функцию возврата обещания:

delay(1000).then(() => console.log("One second passed")).
            then(() => delay(1000)).
            then(() => console.log("Another second passed"));


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow