Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
}
Приведенный ниже код дает вам исключение с нулевым указателем.
public class School {
Student obj_Student;
public School() {
try {
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Поскольку вы используете Obj_Student
, но вы забыли инициализировать его, как в правильном коде, показанном ниже:
public class School {
Student obj_Student;
public School() {
try {
obj_Student = new Student();
obj_Student.setId(12);
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Если у нее есть функция .then
- это стандартные библиотеки обещаний , только .
В спецификации Promises / A + есть понятие, называемое then
, которое в основном является «объектом с методом then
». Обещания будут и должны ассимилировать все с помощью метода then. Все обещания, о которых вы говорили, делают это.
Если мы посмотрим на спецификацию :
2.3.3.3, если
blockquote>then
это функция, назовите ее с x как это, первый аргумент solvePromise и второй аргумент rejectPromiseОн также объясняет обоснование этого дизайнерского решения:
Эта обработка
blockquote>then
ables позволяет реализовать обеими реализациями, пока они выставляют метод Promises / A + -compliantthen
. Он также позволяет реализациям Promises / A + «ассимилировать» несоответствующие реализации с разумными тогда методами.Как вы должны решить
Вы не должны - вместо этого назовите
Promise.resolve(x)
(Q(x)
в Q), который всегда преобразует любое значение или внешнееthen
в надежное обещание. Это безопаснее и проще, чем выполнять эти проверки самостоятельно.действительно должен быть уверен?
Вы всегда можете запустить его через набор тестов : D
Чтобы узнать, является ли данный объект родным ES6 Promise, мы можем использовать этот предикат:
function isPromise(value) {
return value && Object.prototype.toString.call(value) === "[object Promise]";
}
Call
ing toString
непосредственно из Object.prototype
возвращает собственное строковое представление данного типа объекта, которое в нашем случае является "[object Promise]"
. Это гарантирует, что данный объект
toString
данного объекта. instanceof
или isPrototypeOf
. Symbol.toStringTag
довольно легко переопределить это в ES2015. См. Object.prototype.toString.call({ get [Symbol.toStringTag]() { return 'Promise' }});
– Benjamin Gruenbaum
3 July 2018 в 13:17
Обновление: это уже не лучший ответ. Пожалуйста, проголосуйте за мой другой ответ .
obj instanceof Promise
должен это сделать. Обратите внимание, что это может работать надежно только с собственными обещаниями es6.
Если вы используете прокладку, библиотеку обещаний или что-то еще, притворяющееся перспективным, тогда может быть более целесообразным протестировать «thenable» (что-нибудь с методом .then
), как показано в других ответах здесь.
Promise.resolve(obj) == obj
не работает в Safari. Вместо этого используйте instanceof Promise
.
– jib
25 September 2015 в 19:45
obj && typeof obj.then == 'function'
вместо этого, потому что он будет работать со всеми типами обещаний и на самом деле является способом, рекомендованным спецификацией и используемым реализациями / полиполками. Нативный Promise.all
, например, будет работать на всех then
ables, а не только на других нативных обещаниях. Так и ваш код. Таким образом, instanceof Promise
не является хорошим решением.
– Stijn de Witt
16 March 2016 в 00:14
console.log(typeof p, p, p instanceof Promise);
производит этот вывод: object Promise { <pending> } false
. Как вы видите, это обещание в порядке - и тем не менее тест instanceof Promise
возвращает false
?
– Mörre
22 June 2016 в 15:42
Проверка того, что что-то обещание излишне усложняет код, просто используйте Promise.resolve
Promise.resolve(valueOrPromiseItDoesntMatter).then(function(value) {
})
Вот мой оригинальный ответ, который с тех пор был ратифицирован в spec как способ проверить обещание:
Promise.resolve(obj) == obj
Это работает, потому что алгоритм явно требует, чтобы Promise.resolve
возвращал точный объект, переданный в if и , только если является обещанием по определению spec.
У меня есть другой ответ здесь, который говорил об этом, но я изменил его на что-то еще, когда он не работал с Safari в то время. Это было год назад, и теперь это работает надежно даже в Safari.
Я бы отредактировал свой первоначальный ответ, за исключением того, что это было неправильно, учитывая, что больше людей проголосовали за измененное решение в этом ответе чем оригинал. Я считаю, что это лучший ответ, и я надеюсь, что вы согласитесь.
Не ответ на полный вопрос, но я думаю, что стоит упомянуть, что в Node.js 10 была добавлена новая функция использования, названная isPromise
, которая проверяет, является ли объект родным обещанием или не:
const utilTypes = require('util').types
const b_Promise = require('bluebird')
utilTypes.isPromise(Promise.resolve(5)) // true
utilTypes.isPromise(b_Promise.resolve(5)) // false
ES6:
const promise = new Promise(resolve => resolve('olá'));
console.log(promise.toString().includes('Promise')); //true
toString
, может просто вернуть строку, которая включает "Promise"
.
– Boghyon Hoffmann
12 January 2018 в 00:11
'NotAPromise'.toString().includes('Promise') === true
– damd
23 January 2018 в 00:05
if (typeof thing.then === 'function') {
// probably a promise
} else {
// definitely not a promise
}
thing
обещанием или нет, поскольку любая вещь i> может иметь метод с именем then
..
– Boghyon Hoffmann
27 March 2018 в 14:36
Если вы используете TypScript, я бы хотел добавить, что вы можете использовать функцию «предикат типа». Просто следует обернуть логическую проверку в функции, которая возвращает x is Promise<any>
, и вам не нужно будет делать машинные приемы. Ниже моего примера, c
является обещанием или одним из моих типов, которые я хочу преобразовать в обещание, вызвав метод c.fetch()
.
export function toPromise(c: Container<any> | Promise<any>): Promise<any> {
if (c == null) return Promise.resolve();
return isContainer(c) ? c.fetch() : c;
}
export function isContainer(val: Container<any> | Promise<any>): val is Container<any> {
return val && (<Container<any>>val).fetch !== undefined;
}
export function isPromise(val: Container<any> | Promise<any>): val is Promise<any> {
return val && (<Promise<any>>val).then !== undefined;
}
Дополнительная информация: https : //www.typescriptlang.org/docs/handbook/advanced-types.html
it('should return a promise', function() {
var result = testedFunctionThatReturnsPromise();
expect(result).toBeDefined();
// 3 slightly different ways of verifying a promise
expect(typeof result.then).toBe('function');
expect(result instanceof Promise).toBe(true);
expect(result).toBe(Promise.resolve(result));
});
после поиска надежного способа обнаружения функций Async или даже Promises, я закончил использование следующего теста:
() => fn.constructor.name === 'Promise' || fn.constructor.name === 'AsyncFunction'
Promise
и создаете экземпляры этого, этот тест может завершиться неудачно. это должно работать для большей части того, что вы пытаетесь проверить, хотя.
– theram
31 May 2018 в 17:17
fn.constructor.name === 'AsyncFunction'
неверно - это означает, что что-то является функцией асинхронного вызова, а не обещанием - также не гарантируется работа, потому что люди могут подклассы обещать
– Benjamin Gruenbaum
3 July 2018 в 13:15
Вот форма кода https://github.com/ssnau/xkit/blob/master/util/is-promise.js
!!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
, если объект с методом then
, его следует рассматривать как Promise
.
Если вы используете метод async, вы можете сделать это и избежать любой двусмысленности
async myMethod(promiseOrNot){
const theValue = await promiseOrNot
}
Promise.resolve
ничего не скажет вам и преобразует объекты в процесс , Таким образом, на самом деле ответ будет (с учетом объекта с именемsubject
):var isPromise = typeof subject.then == 'function';
– Stijn de Witt 15 March 2016 в 23:18then
, но все методыthen
не принадлежат кPromise
. Поэтому ваше заявление недействительно, поэтому не отвечайте на вопрос. – Oleander 24 August 2016 в 17:24then
, то он будет рассматриваться как обещание и должен быть рекурсивно ассимилирован с помощьюPromise.prototype.then
,Promise.resolve
all
race
или параметраfulfill
конструктора обещаний. Таким образом, вы можете i> технически проверить по-другому, но сам язык проверяет часто, и он проверяет это. Я не уверен, что означает ваш downvote или что не так, потому что раздел, который вы комментируете, начинается с «Как решает библиотека обещаний». и это правильно – Benjamin Gruenbaum 24 August 2016 в 19:49How do I test to see if a given object is a Promise?
. То есть; если у вас есть какой-либо объект, то каким образом это происходит, если этоPromise
или нет. Проверка существованияthen
подскажет вам, что объект является либоPromise
, либоObject
методомthen
, поэтому не отвечает на данный вопрос. Это увеличивает вероятность того, что объект являетсяPromise
, но это все. – Oleander 24 August 2016 в 20:07